jQuery: Cross-browser problem — Debugging Internet

2019-06-26 00:24发布

问题:

Update: The issue seems to be that due to the JavaScript that was written to acccomodate a problem with Firefox/flash, the program is now trying to play html5 in IE, which isn't working for IE 8 and earlier. However, if I put a javascript based html5 link in the header http://html5media.info/, the html5 players work in IE 8 but not in any workable way. All the players show at once and start playing automatically. Note, all my students are in Asia so the game sort of has to work in IE 8...

I made a game using jQuery/JavaScript for learners of English as a Second language at game here. It works in Chrome, Firefox and Safari, but not Internet Explorer. I don't know how to figure out the problem in I.E., but it seems like a pretty simple javascript problem that the cross-browser compatability of jQuery shouldn"t have a problem with, unless my code is so bad that I've screwed it up somehow (note that I am a relative newbie)

The game uses 16 different audio recordings, so there are 16 different audio players. However, each audio player is hidden using css

display: none 

and then made to reappear with

.css('display', 'block');

but in IE it's not working

Using JavaScript, I randomly select a number from 1 to 16 and then make one of the audio players visible based on that. It all happens when you click "start" on the game"s home page. However, in I.E., the audio player doesn"t show when I click start. This seems like a fairly basic JavaScript issue that I would have thought jQuery wouldn"t have cross-browser issues with, Note, other parts of the JavaScript appear to work in IE. For example, if you click one of the letters at the bottom of the game, it tells you whether your guess was right or wrong (based on the audio you"re supposed to hear).

I also noticed that in I.E. the page takes a heck of a long time to load (5 minutes later, It still says 16 items remaining at the bottom). I assume those might be the audio players. In other browswers, that doesn't happen.

It's very important for me that the game work in IE because the students I made it for are in Japan, and most of them use IE

Can anyone help me debug this in IE or give me an idea how to debug it in IE?

This is the code that is supposed to make the audio player appear. Depending on whether browser uses Flash or HTML5 (which is detected with the line if ($('#ONE').length) ), jQuery then either uses "show" or .css('display', 'block') to make the audio player appear. Assuming IE is choosing flash, then it is using

.css('display', 'block') 

to make the audio player appear (unsuccessfully)

jQuery to make audio player appear

function test() {
    $(".start").click(function() {

        ran = getRandom(myArray, true);

            if ($('#ONE').length) { 
            $( '#' + ran ).show();
         } 
            else { 
             $('#f-' + ran).css('display', 'block');

         }

         });

Update, this is the PHP file from the audio plugin

## WPaudio version
$wpa_version = '3.1';

## Pre-2.6 compatibility (from WP codex)
if ( ! defined( 'WP_CONTENT_URL' ) )
    define( 'WP_CONTENT_URL', get_option( 'siteurl' ) . '/wp-content' );
if ( ! defined( 'WP_CONTENT_DIR' ) )
    define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' );
if ( ! defined( 'WP_PLUGIN_URL' ) )
    define( 'WP_PLUGIN_URL', WP_CONTENT_URL. '/plugins' );
if ( ! defined( 'WP_PLUGIN_DIR' ) )
    define( 'WP_PLUGIN_DIR', WP_CONTENT_DIR . '/plugins' );
if ( ! defined( 'WPAUDIO_URL' ) )
    define( 'WPAUDIO_URL', WP_PLUGIN_URL . '/wpaudio-mp3-player' );

## Get WPaudio's options from DB (or create them if not found)
$wpa_options = wpaOptions();

## WP handlers - add WPaudio processing at necessary events
# If it's not an admin page, get everything for the player
if ( !is_admin() ) {
    # Calling scripts
    add_action('init', 'wpaLibraries');
    # Add header action to include CSS and JS vars
    add_action('wp_head', 'wpaHead');
    # Add shortcode for WPaudio player
    add_shortcode('wpaudio', 'wpaShortcode');
    # Add filter for shortcode in excerpt and widgets
    add_filter('the_excerpt', 'do_shortcode');
    add_filter('widget_text', 'do_shortcode');
    # Add filter for non-shortcode substitutes (including excerpts and widgets)
    if ($wpa_options['wpa_tag_audio']) {
        add_filter('the_content', 'wpaFilter');
        add_filter('the_excerpt', 'wpaFilter');
        add_filter('widget_text', 'wpaFilter');
    }
}
# Add admin
add_action('admin_menu', 'wpa_menu');
# Add track
if ($wpa_options['wpa_track_permalink']) add_action('publish_post', 'wpaPostNew');

function wpaOptions(){
    ## WPA options and defaults
    global $wpa_version;
    $wpa_options = Array(
        'wpa_version' => $wpa_version,
        'wpa_pref_link_mp3' => 0,
        'wpa_tag_audio' => 0,
        'wpa_track_permalink' => 1,
        'wpa_style_text_font' => 'Sans-serif',
        'wpa_style_text_size' => '18px',
        'wpa_style_text_weight' => 'normal',
        'wpa_style_text_letter_spacing' => 'normal',
        'wpa_style_text_color' => 'inherit',
        'wpa_style_link_color' => '#24f',
        'wpa_style_link_hover_color' => '#02f',
        'wpa_style_bar_base_bg' => '#eee',
        'wpa_style_bar_load_bg' => '#ccc',
        'wpa_style_bar_position_bg' => '#46f',
        'wpa_style_sub_color' => '#aaa'
    );
    if ( $wpa_options_db = get_option( 'wpaudio_options' ) ) {
        foreach ( $wpa_options as $key => $value ) {
            if ( isset($wpa_options_db[$key]) ) {
                $wpa_options[$key] = $wpa_options_db[$key];
            }
        }
    }
    else {
        # Get legacy options and remove if they exist
        if ( get_option('wpa_tag_audio') ) {
            foreach ($wpa_options as $key => $value) {
                $wpa_option_old_db = get_option($key);
                if ( $wpa_option_old_db !== false && $wpa_option_old_db !== '' ) {
                    $wpa_options[$key] = $wpa_option_old_db;
                }
                delete_option($key);
            }
        }
        # Create wpaudio_options
        add_option('wpaudio_options', $wpa_options, '', 'no');
        //update_option('wpaudio_options', $wpa_options);
    }
    return $wpa_options;
}

## Built-in libraries
function wpaLibraries(){
    global $wpa_version;
    //wp_deregister_script( 'jquery' );
    //wp_register_script( 'jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js', '1.4.3' );
    if ( version_compare( get_bloginfo( 'version' ), '2.8', '>=' ) ) {
        if ( WP_DEBUG === false ) {
            wp_register_script( 'wpaudio', WPAUDIO_URL . '/wpaudio.min.js', Array('jquery'), $wpa_version, true );
        }
        else {
            wp_register_script( 'wpaudio', WPAUDIO_URL . '/wpaudio.js', Array('jquery'), $wpa_version, true);
        }
        wp_enqueue_script( 'wpaudio' );
    }
    else {
        wp_enqueue_script('jquery');
        add_action('wp_footer', 'wpaFooterForOldVersions');
    }
}

## WPaudio style, jQuery, SWFObject
function wpaHead(){
    global $wpa_options;
    # Put all styles into the _wpaudio settings object
    $style = '';
    foreach ( $wpa_options as $key => $value ) {
        $exploded = explode('_', $key, 3);
        if ( $exploded[1] == 'style' ) {
            $style .= $exploded[2] . ":'$value',";
        }
    }
    $style = trim( $style, ',' );
    $style = '{' . $style . '}';
    # Common JS
    $wpa_pref_link_mp3 = ($wpa_options['wpa_pref_link_mp3']) ? 'true' : 'false';
    $head = "<script type='text/javascript'>/* <![CDATA[ */ var _wpaudio = {url: '" . WPAUDIO_URL . "', enc: {}, convert_mp3_links: $wpa_pref_link_mp3, style: $style}; /* ]]> */</script>";
    echo $head;
}

function wpaFooterForOldVersions() {
    echo '<script type="text/javascript" src="' . WPAUDIO_URL . '/wpaudio.min.js"></script>';
}

# Used only for wpaudio shortcode tags
function wpaShortcode($atts){
    # Convert shortcodes to WPaudio player depending on settings
    extract(shortcode_atts(Array(
        'url' => false,
        'text' => false,
        'dl' => true,
        'autoplay' => false
    ), $atts));
    # If no url, return with nothing
    if (!$url)
        return;
    # Get player HTML and JS
    return wpaLink($url, $text, $dl, $autoplay);
}

# Make WPA link
function wpaLink($url, $text = false, $dl = true, $autoplay = false) {
    $id = uniqid('wpaudio-');
    $class = 'wpaudio';
    $html = '';
    # Handle dl URLs and no dl players
    if ($dl == '0') {
        $js_url = wpaUnicode($url);
        $href = '#';
        $class .= ' wpaudio-nodl';
    }
    elseif (is_string($dl)) {
        $js_url = wpaUnicode($url);
        $href = $dl;
    }
    else {
        $href = $url;
    }
    if (isset($js_url)) {
        $class .= ' wpaudio-enc';
        $html .= "<script type='text/javascript'>_wpaudio.enc['$id'] = '$js_url';</script>";
    }
    # Handle blank text
    if (!$text) {
        $text = basename($url);
        $class .= ' wpaudio-readid3';
    }
    # Autoplay
    if ($autoplay == '1') {
        $class .= ' wpaudio-autoplay';
    }
    $html .= "<a id='$id' class='$class' href='$href'>$text</a>";
    return $html;
}

# Used for audio tags
function wpaFilter($content){
    ## Convert audio tags and links to WPaudio player depending on settings
    $tag_regex = '/\[audio:(.*?)\]/';
    $tag_match = preg_match_all($tag_regex, $content, $tag_matches);
    # Replace audio tags with player links
    if ($tag_match){
        foreach ($tag_matches[1] as $key => $value){
            # This is one tag, first get parameters and URLs
            $params = explode('|', $value);
            $clips = Array('urls' => Array(), 'titles' => Array(), 'artists' => Array());
            $clips['urls'] = explode(',', $params[0]);
            # Process extra parameters if they exist
            for ($i=1; $i<count($params); $i++) {
                # Get the parameter name and value
                $param = explode('=', $params[$i]);
                if ($param[0] == 'titles' || $param[0] == 'artists')
                    $clips[$param[0]] = explode(',', $param[1]);
            }
            # Get player(s)
            $player = '';
            foreach ($clips['urls'] as $ukey => $uvalue) {
                $text = '';
                $text .= (isset($clips['artists'][$ukey])) ? $clips['artists'][$ukey] : '';
                $text .= (isset($clips['artists'][$ukey]) && isset($clips['titles'][$ukey])) ? ' - ' : '';
                $text .= (isset($clips['titles'][$ukey])) ? $clips['titles'][$ukey] : '';
                if (!$text) $text = false;
                $player .= wpaLink($uvalue, $text);
            }
            $content = str_replace($tag_matches[0][$key], $player, $content);
        }
    }
    return $content;
}

# Convert string to unicode (to conceal mp3 URLs)
include 'php-utf8/utf8.inc';
function wpaUnicode($str){
    $uni = utf8ToUnicode(utf8_encode($str));
    $output = '';
    foreach ($uni as $value){
        $output .= '\u' . str_pad(dechex($value), 4, '0', STR_PAD_LEFT);
    }
    return $output;
}

## WP admin menu
function wpa_menu() {
    add_options_page('WPaudio Options', 'WPaudio', 'switch_themes', __FILE__, 'wpa_menu_page');
}
function wpa_menu_page() {
    global $wpa_options;
    if ($_POST) {
        # Checkboxes need values
        $wpa_checkboxes = Array(
            'wpa_pref_link_mp3',
            'wpa_tag_audio',
            'wpa_track_permalink'
        );
        foreach ($wpa_checkboxes as $value) {
            $_POST[$value] = (isset($_POST[$value]) && $_POST[$value]) ? 1 : 0;
        }
        # Now process and save all options
        foreach ($wpa_options as $key => $value) {
            if (isset($_POST[$key]) && !is_null($_POST[$key]) && $_POST[$key] !== '')
                $wpa_options[$key] = $_POST[$key];
        }
        update_option('wpaudio_options', $wpa_options);
    }
    wpaOptions();
    ?>
<!-- wpa menu begin -->
<div class="wrap">
<h2>WPaudio Options</h2>
<form method="POST" action="">
<?php wp_nonce_field('update-options'); ?>

<div id="poststuff" class="metabox-holder">
    <div class="meta-box-sortables">
        <div class="postbox">
            <h3 class="hndle"><span>Links</span></h3>
            <div class="inside">
                <ul>
                    <li>WPaudio will always convert links with the <span style="font-family: Courier, Serif">wpaudio</span> class.  You optionally handle ALL mp3 links too.</li>
                    <li><label for="wpa_pref_link_mp3"><input name="wpa_pref_link_mp3" id="wpa_pref_link_mp3" type="checkbox" <?php if ($wpa_options['wpa_pref_link_mp3']) echo ' checked="yes"'; ?>>
                        Convert all mp3 links - <span style="font-family: Courier, Serif">&lt;a href="http://domain.com/song.mp3"&gt;Link&lt;/a&gt;</span></label></li>
                </ul>
            </div>
        </div>
        <div class="postbox">
            <h3 class="hndle"><span>Tags</span></h3>
            <div class="inside">
                <ul>
                    <li>WPaudio will always convert <span style="font-family: Courier, Serif">[wpaudio]</span> tags, but it can also handle tags from other audio players.</li>
                    <li><label for="wpa_tag_audio"><input name="wpa_tag_audio" id="wpa_tag_audio" type="checkbox" <?php if ($wpa_options['wpa_tag_audio']) echo ' checked="yes"'; ?>>
                        Handle Audio Player tags - <span style="font-family: Courier, Serif">[audio:http://domain.com/song.mp3]</span></label></li>
                </ul>
            </div>
        </div>
        <div class="postbox">
            <h3 class="hndle"><span>Style</span></h3>
            <div class="inside">
                <ul>
                    <li><a href="#" onclick="jQuery('.wpa_style_advanced').css('display', 'block');">It's not necessary to adjust these settings, but click here for advanced options.</a></li>
                </ul>
                <ul class="wpa_style_advanced" style="display: none;">
                    <li>Optionally customize WPaudio's font</li>
                    <li><label for="wpa_style_text_font"><input type="text" name="wpa_style_text_font" id="wpa_style_text_font" value="<?php echo $wpa_options['wpa_style_text_font']; ?>"> Font face</label></li>
                    <li><label for="wpa_style_text_size"><input type="text" name="wpa_style_text_size" id="wpa_style_text_size" value="<?php echo $wpa_options['wpa_style_text_size']; ?>"> Font size</label></li>
                    <li><label for="wpa_style_text_weight"><select name="wpa_style_text_weight" id="wpa_style_text_weight">
                        <option value="inherit" <?php if ($wpa_options['wpa_style_text_weight'] == 'inherit') echo ' selected'; ?>>Inherit</option>
                        <option value="normal" <?php if ($wpa_options['wpa_style_text_weight'] == 'normal') echo ' selected'; ?>>Normal</option>
                        <option value="bold" <?php if ($wpa_options['wpa_style_text_weight'] == 'bold') echo ' selected'; ?>>Bold</option>
                        </select> Font weight</label></li>
                    <li><label for="wpa_style_text_letter_spacing"><input type="text" name="wpa_style_text_letter_spacing" id="wpa_style_text_letter_spacing" value="<?php echo $wpa_options['wpa_style_text_letter_spacing']; ?>"> Letter spacing</label></li>
                </ul>
                <ul class="wpa_style_advanced" style="display: none;">
                    <li>Optionally customize colors (Most commonly 3 or 6 character <a href="http://en.wikipedia.org/wiki/Web_colors#Color_table" target="_blank">hex codes</a>.  For example: <span style="font-family: Courier, Serif">#2244ff</span>)</li>
                    <li><label for="wpa_style_text_color"><input type="text" name="wpa_style_text_color" id="wpa_style_text_color" value="<?php echo $wpa_options['wpa_style_text_color']; ?>" size="7"> Text color</label></li>
                    <li><label for="wpa_style_link_color"><input type="text" name="wpa_style_link_color" id="wpa_style_link_color" value="<?php echo $wpa_options['wpa_style_link_color']; ?>" size="7"> Link color</label></li>
                    <li><label for="wpa_style_link_hover_color"><input type="text" name="wpa_style_link_hover_color" id="wpa_style_link_hover_color" value="<?php echo $wpa_options['wpa_style_link_hover_color']; ?>" size="7"> Link hover color</label></li>
                    <li><label for="wpa_style_bar_base_bg"><input type="text" name="wpa_style_bar_base_bg" id="wpa_style_bar_base_bg" value="<?php echo $wpa_options['wpa_style_bar_base_bg']; ?>" size="7"> Bar base background</label></li>
                    <li><label for="wpa_style_bar_load_bg"><input type="text" name="wpa_style_bar_load_bg" id="wpa_style_bar_load_bg" value="<?php echo $wpa_options['wpa_style_bar_load_bg']; ?>" size="7"> Bar load background</label></li>
                    <li><label for="wpa_style_bar_position_bg"><input type="text" name="wpa_style_bar_position_bg" id="wpa_style_bar_position_bg" value="<?php echo $wpa_options['wpa_style_bar_position_bg']; ?>" size="7"> Bar position background</label></li>
                </ul>
            </div>
        </div>
        <div class="postbox">
            <h3 class="hndle"><span>Notification</span></h3>
            <div class="inside">
                <ul>
                    <li>I love seeing who's using my plugin!  Please select this option to enable a notification when a post containing the player is published so I can come check out your site.  Your blog may even be featured on WPaudio.com.  Thanks!</li>
                    <li><label for="wpa_track_permalink"><input name="wpa_track_permalink" id="wpa_track_permalink" type="checkbox" <?php if ($wpa_options['wpa_track_permalink']) echo ' checked="yes"'; ?>>
                        Allow WPaudio notification</label></li>
                </ul>
            </div>
        </div>
    </div>
</div>

<p class="submit">
    <input class="button-primary" type="submit" value="Save Changes">
</p>

</form>
</div>
<!-- wpa menu end -->
<?php
}

## WP new post - add ping if contains wpaudio
function wpaPostNew($id) {
    $post = get_post($id);
    if (strpos(strtolower($post->post_content), 'wpaudio') !== false) {
        $permalink = rawurlencode(get_permalink($id));
        if (function_exists('curl_init') && function_exists('curl_setopt') && function_exists('curl_exec') && function_exists('curl_close')) {
            $ch = curl_init("http://wpaudio.com/t/?url_post=$permalink");
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HEADER, 0);
            curl_exec($ch);
            curl_close($ch);
        }
    }
}

?>

回答1:

Can anyone help me debug this in IE or give me an idea how to debug it in IE?

If you're on at least IE8, the developer tools are helpful. They're even better in IE9. As long as you've got the developer console open, sprinkling console.log statements around can help find what line(s) your code is borking on. Be careful to remove then once you're done though - console.log breaks IE if you have the developer window closed.

I also noticed that in I.E. the page takes a heck of a long time to load (5 minutes later, It still says 16 items remaining at the bottom). I assume those might be the audio players. In other browswers, that doesn't happen.

I've got a hunch this is the main cause of your problems. Fiddler should help show you what network requests are still waiting, as will the network tab in the IE9 developer tools



回答2:

It may be because you're calling them with a click function? What happens if you use a live function instead?


function test() {
   $('.start').live('click', function() {
      ran = getRandom(myArray, true);
      if ($('#ONE').length) { 
         $( '#' + ran ).show();
      } 
      else { 
         $('#f-' + ran).css('display', 'block');
      };
});
}



回答3:

Try setting the display property to empty:

.css('display', '')


回答4:

Alright... based off your source I got it "functioning" although your probably want to consolidate your script

Here is the minor change to the html (beside moving the script out)

<div class="audio_wrap html5audio">
    <div id="f-ONE" style="display: none;">
        <a href="http://eslangel.com/wp-content/uploads/2011/07/one2.mp3" title="Click to open"
            id="f-ONE">Audio MP3</a></div>
    <audio controls autobuffer id="ONE" class="html5audio"><source src="http://eslangel.com/wp-content/uploads/2011/07/one2.mp3" type="audio/mpeg" />
    <a href="http://eslangel.com/wp-content/uploads/2011/07/one2.mp3" title="Click to open" id="f-ONE">Audio MP3</a>
    </audio>
</div>

You can see that I gave the inner div an id of "f-ONE". You will need to do this for all divs. This markup could definitely be cleaned up.

Then I modified this script:

// see if the canvas element is supported so we know it's html5
if (!!document.createElement('canvas').getContext) {
    jQuery("div.audio_wrap div").remove();
} else {
    jQuery("audio").remove();
    jQuery("div.audio_wrap div").show();
}

So I remove your audio tags when it is not supported by the browser. I am pretty sure this is the root of your problem since the player was not degrading gracefully. Maybe the anchor tag "f-ONE" was supposed to be outside of the audio element?



回答5:

Your problem is actually not a JavaScript problem.

For some reason, when the server side code detects an IE client, it serves audio in HTML5 format ("audio" tag) when it should give the browser a Flash file. Unfortunately, out of the major browsers, IE has the most terrible support for HTML5; your audio file was never understood/loaded in the first place.

On the other hand, Firefox, which supports HTML5, is given a Flash audio player. Somewhere in your server code, there is a conditional statement that needs to be reversed.

Hope this helps.



回答6:

So if all the audio files are visible initially, they play fine?

If that is the case, can you just set the width/height to 0px and expand it when a selection is made?