WordPress - 仅为低于IE 9的浏览器加载脚本

31
在WordPress主题中,如何有条件地包含ie8及以下版本的脚本?这主要是为了应用各种HTML5/CSS3功能的polyfill。我发现WordPress有一个$is_IE变量,可以用作条件来仅为IE包含脚本。但是否有一种方法仅针对特定版本的IE添加脚本,而不是所有版本?在HTML中使用一些IE条件注释很简单,但我想将所有脚本都放在同一个位置的functions文件中。
HTML中特定版本的条件: <!--[if lt IE 9]> <script src="iepolyfill.min.js"></script> <![endif]--> WP中所有IE的条件:
    global $is_IE;

    if ( $is_IE ) {
        wp_enqueue_script( 'iepolyfill', bloginfo('stylesheet_directory').'/js/iepolyfill.min.js' );
    }

我已经搜索了一些内容,主要是关于仅限于 WordPress 后端的条件脚本的详细信息。

有什么建议吗?

7个回答

74

适用于WordPress 4.2及以上版本

使用wp_script_add_data将脚本包装在条件注释中:

wp_enqueue_script( 'html5shiv', '//cdn.jsdelivr.net/html5shiv/3.7.2/html5shiv.js' );
wp_script_add_data( 'html5shiv', 'conditional', 'lt IE 9' );

wp_enqueue_script( 'respond', get_template_directory_uri() . '/js/respond.min.js' );
wp_script_add_data( 'respond', 'conditional', 'lt IE 9' );

确保在调用wp_script_add_data之前注册脚本(注册由上面的wp_enqueue_script处理),并且您传递给wp_script_add_data的第一个参数与注册脚本时传递的第一个参数相匹配。


对于WordPress 4.1:

今天,您可以使用script_loader_tag过滤器将带有条件注释的脚本添加到队列中。以下是一个示例实现:

wp_enqueue_script( 'html5shiv', '//cdn.jsdelivr.net/html5shiv/3.7.2/html5shiv.js', array(), '3.7.2', false );
add_filter( 'script_loader_tag', function( $tag, $handle ) {
    if ( $handle === 'html5shiv' ) {
        $tag = "<!--[if lt IE 9]>$tag<![endif]-->";
    }
    return $tag;
}, 10, 2 );

如果你想以相同的方式包含多个脚本,可以使用以下类似的方法:

// Conditional polyfills
$conditional_scripts = array(
    'html5shiv'           => '//cdn.jsdelivr.net/html5shiv/3.7.2/html5shiv.js',
    'html5shiv-printshiv' => '//cdn.jsdelivr.net/html5shiv/3.7.2/html5shiv-printshiv.js',
    'respond'             => '//cdn.jsdelivr.net/respond/1.4.2/respond.min.js'
);
foreach ( $conditional_scripts as $handle => $src ) {
    wp_enqueue_script( $handle, $src, array(), '', false );
}
add_filter( 'script_loader_tag', function( $tag, $handle ) use ( $conditional_scripts ) {
    if ( array_key_exists( $handle, $conditional_scripts ) ) {
        $tag = "<!--[if lt IE 9]>$tag<![endif]-->";
    }
    return $tag;
}, 10, 2 );

我通过谷歌找到了这个答案,因为我遇到了与OP相同的问题。这是一个很好的答案,但即使使用匿名函数的示例也不是很好,因为您没有通过WordPress正确加载脚本。根据您使用的插件,这可能会导致问题,因为您可能会加载相同的脚本两次,因此始终注意WordPress实际打印的HTML。 - Sven
我认为这样做还可以,但实际上并没有比直接在header.php文件中硬编码更好,个人观点。 - Mulan
1
看起来这将成为4.2的一部分!https://core.trac.wordpress.org/ticket/16024 - Kyle Ridolfo
1
这是在4.2中添加的吗? - Neil
1
@ClarusDignus 我添加了一个使用条件注释加载脚本的 WP 4.2+ 版本示例。这样清楚明白了吗,还有疑问吗? - Andrew Patton
显示剩余5条评论

24
  • 每当您在WP主题或插件中添加脚本时,都应使用wp_register_script()
  • 服务器端嗅探通常不是一个好主意,因为它并不确定。
  • 通常您需要针对缺少某些功能的浏览器进行定位,而不一定只是IE浏览器。 Modernzr是执行此操作的优秀脚本。

对于IE,条件标签非常有效。以下是如何将条件标签添加到脚本中的示例,例如HTML5shiv

global $wp_scripts;
wp_register_script( 
    'html5shiv', 
    get_bloginfo('template_url').'/assets/js/html5shiv.js', 
    array(), 
    '3.6.2'
    );
$wp_scripts->add_data( 'html5shiv', 'conditional', 'lt IE 9' );

2
这仅适用于$wp_styles。相关票证:#16024 - brasofilo
是的,这个不行。检查一下源代码输出。脚本周围没有条件注释。 - Mulan
抱歉对Mikael说,这确实需要被投票否决,以便人们不认为它是可行的解决方案。 - MatthewLee
1
终于,在WP 4.2中这将会起作用!https://core.trac.wordpress.org/ticket/16024 - Andrew Patton

8

WordPress 4.2及以上版本的解决方案

正确的方法是应用wp_enqueue_script,因为这里涉及JavaScript,而不是CSS样式。此外,最好使用get_bloginfo('stylesheet_url')来确保在子主题中也可以正常工作。

/**
 * IE Fallbacks
 */

function load_IE_fallback() {
    wp_register_script( 'ie_html5shiv', get_bloginfo('stylesheet_url'). '/js/html5shiv.min.js', __FILE__, false, '3.7.2' );
    wp_enqueue_script( 'ie_html5shiv');
    wp_script_add_data( 'ie_html5shiv', 'conditional', 'lt IE 9' );

    wp_register_script( 'ie_respond', get_bloginfo('stylesheet_url'). '/js/respond.min.js', __FILE__, false, '1.4.2' );
    wp_enqueue_script( 'ie_respond');
    wp_script_add_data( 'ie_respond', 'conditional', 'lt IE 9' );
}
add_action( 'wp_enqueue_scripts', 'load_IE_fallback' ); 

我本来也想加上完全相同的内容,但是我看到你已经做了。我已经测试过这个代码,在我的主题的functions.php中使用get_template_directory_uri().'/js/lib/excanvas.js'可以正常工作。 - vahanpwns
感谢您提供这个答案。没有什么比问问题者找到答案却不愿意为其他人分解它更让我恼火了。 - Clarus Dignus

8

使用CDN加载脚本的WordPress 4.7.3更新:

    add_action( 'wp_enqueue_scripts', 'load_IE_fallback' );
function load_IE_fallback() {
    wp_register_script( 'ie_html5shiv', 'https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js', '', '3.7.3', false );
    wp_register_script( 'ie_respond', 'https://oss.maxcdn.com/respond/1.4.2/respond.min.js', '', '1.4.2', false );

    wp_enqueue_script( 'ie_html5shiv');
    wp_enqueue_script( 'ie_respond');

    wp_script_add_data( 'ie_html5shiv', 'conditional', 'lt IE 9' );    
    wp_script_add_data( 'ie_respond', 'conditional', 'lt IE 9' );
}

2
最好的方法是将脚本加入队列,然后使用 wp_style_add_data() 来设置条件。这种方法被官方主题如 twenty thirteen 所使用。
有一个类似的答案,但他在条件中添加了额外的 if,这是错误的。
wp_register_style( 'ie_html5shiv', get_template_directory_uri() . '/js/html5shiv.js' );
    wp_enqueue_style( 'ie_html5shiv');
    wp_style_add_data( 'ie_html5shiv', 'conditional', 'lt IE 9' );

    wp_register_style( 'ie_respond', get_template_directory_uri() . '/js/respond.min.js' );
    wp_enqueue_style( 'ie_respond');
    wp_style_add_data( 'ie_respond', 'conditional', 'lt IE 9' );

不错的发现。对于这样一个小改变,您可以提出更改或在类似的答案上发表评论。 - Bryan Willis

1

尝试使用wp_style_add_data()函数(官方在twentythirteentwentyfourteen主题中使用):

wp_enqueue_style( 'iepolyfill', bloginfo( 'stylesheet_directory' ) . '/js/iepolyfill.min.js' );
wp_style_add_data( 'iepolyfill', 'conditional', 'if lt IE 9' );

更新:自WordPress >= 4.2.0版本以来,有一个与此相同的函数可供使用,它被称为:

wp_script_add_data()

你确认使用 wp_style 逻辑添加 JavaScript 没有意外或负面影响吗?它会将文件作为 <script> 元素而不是 <link> 元素添加吗? - Andrew Patton
2
这段代码生成的是包含CSS文件的HTML,而不是Javascript。 - Maxime

1

10
答案不完整。这并未解决如何在使用 wp_enqueue_script 将 JavaScript 添加到主题时实际注入一个条件语句的问题。 - Mulan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接