WordPress稳妥的加载JQuery库(防止CDN外链失效)

!本文可能 超过1年没有更新,今后内容也许不会被维护或者支持,部分内容可能具有时效性,涉及技术细节或者软件使用方面,本人不保证相应的兼容和可操作性。

这个是制作主题时遇到的,因为引用了JQuery脚本库,为了最佳的浏览体验,当然希望这个脚本库加载得越快越好,或者我们的主机商限制了流量,JQuery几十K的流量也要勒紧裤带啊,所以我们会考虑CDN,国内外流行的JQuery CDN有Google的或者Sina云计划,地址分别是:

http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
http://lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js

然后我们就可以直接用script标签引用了,比如这样:

<script type="text/javascript"
        src="http://lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js">
</script>

好吧,速度问题算是解决了,而且有这些大公司做后盾,我们也不必考虑其他问题,等等,没有其他问题了吗?假如我说假如我使用的这家公司倒闭了呢?好吧,现阶段不可能无缘无故倒闭的;假如链接地址更改了呢?或者被XX了?好吧,这个是我们要考虑的问题,针对XX问题,我们可以选择国内sina的CDN,对于前一个问题,我们就需要考虑容灾措施了,假如这些发生了,我们该怎么做?

我现在博客的流量监控使用的是Google Analytics,发现其采用了如下这么段异步加载的措施:

try {
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-XXXXXX-X']);
  _gaq.push(['_trackPageview']);
 
  (function() {
  var ga = document.createElement('script');
  ga.type = 'text/javascript';
  ga.async = true;
  ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www')
       + '.google-analytics.com/ga.js';
  var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(ga, s);
  })();
}catch(e){}

进一步研究发现通过createElement(‘script’)方法还可以获取其他特性,比如判断脚本是否已经加载完成,这个貌似对于刚才的问题有所帮助哎,于是我改写了这么一段代码:

(function( window, undefined ) {
  window.jQuery || (function(){
    var mirrors = [
      "lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js",
      location.hostname + "/blog/wp-includes/js/jquery/jquery.js"
    ];
    for (var i=0; i<mirrors.length; i++) {
      if(typeof(window.jQuery) == "undefined") {
        var script = document.createElement('script');
        script.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + mirrors[i];
        script.type = 'text/javascript';
        script.language = 'javascript';
        script.async = false;
        script.onload = script.onreadystatechange = function() {
          if (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') {
            // 这里放依赖JQuery执行的代码
            script.onload = script.onreadystatechange = null;
          }
        }
        // document.body.appendChild(script); 这句换下面两句
         var s = document.getElementsByTagName('script')[0];
         s.parentNode.insertBefore(script, s);
      } else {
        break;
      }
    }
  })();
})(window);

想法倒是很好,思路就是通过查询mirrors列表先加载CDN的JQuery库,然后通过typeof(window.jQuery)判断是否加载成功,如果不成功则继续加载mirrors剩下的地址指向的JQuery库,我这里直接写上本地WordPress自带的JQuery库地址。但是实际操作中发现问题多多,主要是异步加载,我也尝试着将async设置为false,但是仍然异步加载脚本,这样导致每次循环typeof(window.jQuery)==undefined,这样导致mirrors里面的库全部被加载了,试了很多次,无果,遂放弃了这个办法

我后来搜索了一下,又找到了一个办法,那就是通过下面的代码来实现加载:

<script type='text/javascript' src='http://lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js'></script>
<script type="text/javascript">
//<![CDATA[
if (typeof jQuery == 'undefined') {
  document.write(unescape("%3Cscript src='/blog/wp-includes/js/jquery/jquery.js' type='text/javascript'%3E%3C/script%3E")); 
}
// ]]>
</script>

也就是说一般加载选择script标签引入CDN地址,如果加载失败也就是typeof jQuery为undefined,那就输出script,并引入本地JQuery库。我用FireBug观察了一下,发现这种方式是阻塞加载,也就是同步的,就不存在刚才遇到的问题了。

对于WordPress可以通过在functions.php里面修改或者加入下面的代码来实现嵌入JQuery库。

function my_init() {
    if (!is_admin()) {
        wp_deregister_script('jquery');
        wp_register_script('jquery',("http://lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js"), false, "1.7.2", false);
        wp_enqueue_script('jquery');
    }
}
add_action('init', 'my_init');

这样head标签里就嵌入了script外链的SinaApp JQuery库,为了能快速渲染页面,有些同学喜欢将其加入页面底部,其实只需要将wp_register_script改成下面这样既可:

wp_register_script('jquery',("http://lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js"), false, "1.7.2", true);

注意最后一个参数,为true时代表将引用JQuery的script标签嵌入页面底部,如果需要加入额外的判断代码,比如刚才的判断JQuery加载失败就引入本地库的那段可以先建立函数my_jquery_reload:

function my_jquery_reload() {
 // 这里输出代码
}

如果加入头部(head)则使用下面的代码:

add_action('wp_head', 'my_jquery_reload');

如果加入底部则使用下面的代码:

add_action('wp_footer', 'my_jquery_reload');

好了,我的介绍完了。

若无特别说明,本网站文章均为原创,原则上这些文章不允许转载,但是如果阁下是出于研究学习目的可以转载到阁下的个人博客或者主页,转载遵循创作共同性“署名-非商业性使用-相同方式共享”原则,请转载时注明作者出处谢绝商业性、非署名、采集站、垃圾站或者纯粹为了流量的转载。谢谢合作!

    • 如果不是受XX的影响,Google的还是蛮稳定的,速度也堪比国内的一些服务商。
      不过现在保险起见,只有选择国内的jQuery CDN了,前提还是要有大公司做后台,免得不稳定或者莫名奇妙的关闭。

请稍后...

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*