jQuery技术

编程技巧:用JQuery异步实现顺序加载外部脚本

字号+ 作者:H5之家 来源:H5之家 2017-04-01 13:00 我要评论( )

用JQuery异步实现顺序加载外部脚本 乍看之下是个矛盾的命题,其实并不矛盾。 异步是什么,大家都知道就不说了,说说同步顺序加载,也很简单。就是假如你有A,B,C三资源需要延迟加载,但又要保证A,B,C之间能顺序加载,同时不阻塞浏览器。 比如:我们需要加载a,

用JQuery异步实现顺序加载外部脚本

乍看之下是个矛盾的命题,其实并不矛盾。

异步是什么,大家都知道就不说了,说说同步顺序加载,也很简单。就是假如你有A,B,C三资源需要延迟加载,但又要保证A,B,C之间能顺序加载,同时不阻塞浏览器。
比如:我们需要加载a,b,c三个js 但是C依赖B,B依赖A,就是说在没有A没有加载完的前提下,如果B中使用了A中的资源那肯定是会出错的。C也是如此。这就有了同步顺序加载的概念,固使用一般的  (例子都为jQuery,其他AJAX框架应该差别不大)

$.ajax(A);
$.ajax(B);
$.ajax(C); 这样并不能保障ABC会顺序加载完,这样先加载完的会先执行。

这样的解决办法很多比如直接<script scr="A.js"></script><script scr="B.js" ></script>。。。这样写在head或者body中,在IE中这是顺序加载的,其他浏览器不知道是否这样,但这会引出一个问题,会阻塞浏览器,比如我们打开一个网页经常看见白屏很久才出现网页内容,这就是在头部加载了过多的信息,比如CSS,javascript,也许我们可以把<script src=""> 这个方法body标签最下方。这样可以让页面快速呈现,但当浏览器解释到<script src=""> 时,将依然阻塞浏览器,就是感觉卡住的说。
这时需求就出来了,我们希望浏览器不被阻塞,那想到的肯定是异步加载资源。我们可以使用jQuery()的异步加载,$.ajax(options),其中有一个选项是async询问你是否异步,默认是异步,如果你设置为false 则同步执行,但这并不能解决问题,依然阻塞浏览器。

很多童鞋应该都想到了那我们就用回调函数来实现同步顺序加载,也就是这样的形式 :
$.ajax(A,function(){
      $.ajax(B,function(){
          $.ajax(C,function(){
                  .......      
          });
    });
});
哦,问题出来了,太难看了。你需要顺序加载的资源过多,而且每加载完一个资源需要执行一些处理方法,那么只要这些资源大概上了10个,那么这个缩进就灰常难看了,而且如果你开发中期需求改变,需要换加一个资源或者删一个资源就悲剧了,眼睛都看花,而且地球人都知道javascript出错,是最悲剧的,那个找错误啊。

这个问题出自我现在正在写的一个个人项目,全凭兴趣而作,下面给出我的解决方案:

function createLoadComponent() {
 return {
  textContainer : null,
  setContainer: function(container){this.textContainer=container;},
  println : function(data) {
   this.textContainer.text("开始加载" + data + "...");
  },
  dataURLs : new Array(),
  datasCount : 0,
  count:0,
  traverse : function(obj) {
   if (!obj)
    obj = this;
   var dataURL = obj.dataURLs[this.datasCount];
   if (!dataURL)
   {
    for(var i=0;i<obj.onCompletes.length;i+=1)
     obj.onCompletes[i]();
    this.clear(obj);
    return;
   }
   if (dataURL.name&&obj.textContainer)
    obj.println(dataURL.name);
   obj.datasCount += 1;
   $.ajax( {
    url : dataURL.url,
    dataType : dataURL.type ? dataURL.type : "script",
    success : function(data, textStatus) {
     if (dataURL.callBack)
       dataURL.callBack(data);
     obj.traverse(obj);
    }
   });
  },
  eventCount:0,
  ready:function(callBack){
   this.onCompletes[this.eventCount]=callBack;
   this.eventCount+=1;
  },
  onCompletes:new Array(),
  addURL:function(_url,_name,_type,_callBack)
  {
   
   this.dataURLs[this.count]={name:_name,url:_url,type:_type,callBack:_callBack};
   this.count+=1;
   return this;
  },
  clear : function(obj) {
   if(obj)
    obj=this;
   obj==null;
  }
 }
}

这是个异步顺序加载器(姑且就这么叫吧)看个使用例子:
var loadComponent = createLoadComponent();   
loadComponent.addURL("/main.jsp","主页面","html",function(data) {$(document.body).append(data);});   
loadComponent.addURL("/js/comopent/tooltip/jquery.bgiframe.js","标签提示组件");   
loadComponent.addURL("/js/comopent/tooltip/jquery.dimensions.js");   
loadComponent.addURL("/js/comopent/tooltip/jquery.tooltip.min.js");   
loadComponent.addURL("/js/comopent/jquery.validate.js","验证组件");   
loadComponent.addURL("/js/utils/messages_cn.js");   
loadComponent.addURL("/js/comopent/jquery.cookie.js","cookie组件");   
loadComponent.addURL("/js/comopent/jquery.lazyload.js", "延迟加载组件");   
loadComponent.addURL("/js/comopent/jquery.simplemodal.js","模式框组件");   
loadComponent.addURL("/js/comopent/jquery.quickflip.min.js","Flip组件");   
loadComponent.addURL("/js/mode/UserEntity.js","用户实体");   
loadComponent.addURL("/js/controller/registController.js","注册控制器");   
loadComponent.addURL("/js/controller/loginController.js","登录控制器");   
loadComponent.addURL("/js/controller/errorController.js","错误控制器");   
loadComponent.setContainer($("#loadtext"));   
loadComponent.ready(initMain);   
loadComponent.traverse();  
 

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 专栏:JQuery学习

    专栏:JQuery学习

    2017-04-01 15:01

  • 浅谈jQuery插件扩展extend的实现原理

    浅谈jQuery插件扩展extend的实现原理

    2017-04-01 12:05

  • Jquery等待ajax执行完毕再继续执行下面代码的效果

    Jquery等待ajax执行完毕再继续执行下面代码的效果

    2017-04-01 11:08

  • jQuery插件开发学习笔记

    jQuery插件开发学习笔记

    2017-03-31 08:01

网友点评
r