乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      編程技巧:用JQuery異步實(shí)現(xiàn)順序加載外部腳本

       CevenCheng 2012-05-24
       

      編程技巧:用JQuery異步實(shí)現(xiàn)順序加載外部腳本

      分類(lèi): 編程技巧 368人閱讀 評(píng)論(0) 收藏 舉報(bào)

      用JQuery異步實(shí)現(xiàn)順序加載外部腳本

      乍看之下是個(gè)矛盾的命題,其實(shí)并不矛盾。

      異步是什么,大家都知道就不說(shuō)了,說(shuō)說(shuō)同步順序加載,也很簡(jiǎn)單。就是假如你有A,B,C三資源需要延遲加載,但又要保證A,B,C之間能順序加載,同時(shí)不阻塞瀏覽器。
      比如:我們需要加載a,b,c三個(gè)js 但是C依賴(lài)B,B依賴(lài)A,就是說(shuō)在沒(méi)有A沒(méi)有加載完的前提下,如果B中使用了A中的資源那肯定是會(huì)出錯(cuò)的。C也是如此。這就有了同步順序加載的概念,固使用一般的  (例子都為jQuery,其他AJAX框架應(yīng)該差別不大)

      $.ajax(A);
      $.ajax(B);
      $.ajax(C); 這樣并不能保障ABC會(huì)順序加載完,這樣先加載完的會(huì)先執(zhí)行。

      這樣的解決辦法很多比如直接<script scr="A.js"></script><script scr="B.js" ></script>。。。這樣寫(xiě)在head或者body中,在IE中這是順序加載的,其他瀏覽器不知道是否這樣,但這會(huì)引出一個(gè)問(wèn)題,會(huì)阻塞瀏覽器,比如我們打開(kāi)一個(gè)網(wǎng)頁(yè)經(jīng)??匆?jiàn)白屏很久才出現(xiàn)網(wǎng)頁(yè)內(nèi)容,這就是在頭部加載了過(guò)多的信息,比如CSS,javascript,也許我們可以把<script src=""> 這個(gè)方法body標(biāo)簽最下方。這樣可以讓頁(yè)面快速呈現(xiàn),但當(dāng)瀏覽器解釋到<script src=""> 時(shí),將依然阻塞瀏覽器,就是感覺(jué)卡住的說(shuō)。
      這時(shí)需求就出來(lái)了,我們希望瀏覽器不被阻塞,那想到的肯定是異步加載資源。我們可以使用jQuery()的異步加載,$.ajax(options),其中有一個(gè)選項(xiàng)是async詢(xún)問(wèn)你是否異步,默認(rèn)是異步,如果你設(shè)置為false 則同步執(zhí)行,但這并不能解決問(wèn)題,依然阻塞瀏覽器。

      很多童鞋應(yīng)該都想到了那我們就用回調(diào)函數(shù)來(lái)實(shí)現(xiàn)同步順序加載,也就是這樣的形式 :
      $.ajax(A,function(){
            $.ajax(B,function(){
                $.ajax(C,function(){
                        .......      
                });
          });
      });
      哦,問(wèn)題出來(lái)了,太難看了。你需要順序加載的資源過(guò)多,而且每加載完一個(gè)資源需要執(zhí)行一些處理方法,那么只要這些資源大概上了10個(gè),那么這個(gè)縮進(jìn)就灰常難看了,而且如果你開(kāi)發(fā)中期需求改變,需要換加一個(gè)資源或者刪一個(gè)資源就悲劇了,眼睛都看花,而且地球人都知道javascript出錯(cuò),是最悲劇的,那個(gè)找錯(cuò)誤啊。

      這個(gè)問(wèn)題出自我現(xiàn)在正在寫(xiě)的一個(gè)個(gè)人項(xiàng)目,全憑興趣而作,下面給出我的解決方案:

      function createLoadComponent() {
       return {
        textContainer : null,
        setContainer: function(container){this.textContainer=container;},
        println : function(data) {
         this.textContainer.text("開(kāi)始加載" + 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;
        }
       }
      }

      這是個(gè)異步順序加載器(姑且就這么叫吧)看個(gè)使用例子:
      var loadComponent = createLoadComponent();   
      loadComponent.addURL("/main.jsp","主頁(yè)面","html",function(data) {$(document.body).append(data);});   
      loadComponent.addURL("/js/comopent/tooltip/jquery.bgiframe.js","標(biāo)簽提示組件");   
      loadComponent.addURL("/js/comopent/tooltip/jquery.dimensions.js");   
      loadComponent.addURL("/js/comopent/tooltip/jquery.tooltip.min.js");   
      loadComponent.addURL("/js/comopent/jquery.validate.js","驗(yàn)證組件");   
      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","用戶(hù)實(shí)體");   
      loadComponent.addURL("/js/controller/registController.js","注冊(cè)控制器");   
      loadComponent.addURL("/js/controller/loginController.js","登錄控制器");   
      loadComponent.addURL("/js/controller/errorController.js","錯(cuò)誤控制器");   
      loadComponent.setContainer($("#loadtext"));   
      loadComponent.ready(initMain);   
      loadComponent.traverse();  
       

      下面說(shuō)下LoadComponent中的方法:
      setContainer(container)  加載信息輸出容器,不設(shè)置則不輸出,這里的參數(shù)為JQuery對(duì)象,請(qǐng)?jiān)趫?zhí)行traverse()之前調(diào)用。 
      addURL(url,name,type,callBack)添加一個(gè)需加載的腳本,只有URL為必要參數(shù);name為添加的資源名字,如果你設(shè)置了輸出容器,則這個(gè)名字會(huì)在容器中顯示,type為資源類(lèi)型 html, json,xml,script,由于自己項(xiàng)目原因我這里設(shè)置了默認(rèn)值為script,callBack這里的回調(diào)方法是加載完該URL所調(diào)用的方法。
      ready(callBack) 完成加載所有腳本后所執(zhí)行的回調(diào)方法,如上述initMain就會(huì)在所有資源加載完后執(zhí)行,可多次使用ready(callBack)添加多個(gè)回調(diào)方法,按添加順序執(zhí)行,請(qǐng)?jiān)趫?zhí)行traverse()之前調(diào)用。
      traverse() 開(kāi)始同步加載添加的所有URL。執(zhí)行此方法后,會(huì)自動(dòng)執(zhí)行clear() 方法,釋放內(nèi)存,所以,不要在執(zhí)行完traverse()方法后繼續(xù)使用該對(duì)象,應(yīng)從新create一個(gè)新對(duì)象。
      注:LoadComponent是基于jquery寫(xiě)的,所以之前還是需要先讓瀏覽器把jquery加載完,但jquery體積還算是比較小的,無(wú)所謂了。

      ---------------------------------------
      其實(shí),你寫(xiě)的這個(gè)方法效率還是不夠高。因?yàn)樗琼樞蛘?qǐng)求的,而不是并發(fā)請(qǐng)求。
      比如要加載a, b, c這3個(gè)JS文件,你的做法是a請(qǐng)求完成了再請(qǐng)求b,…… 相當(dāng)于總的時(shí)間中還包含了3次http連接建立的時(shí)間。

      其實(shí)要保證運(yùn)行順序,可以3個(gè)文件一起請(qǐng)求。等到都請(qǐng)求完畢后再按順序合并a, b, c,進(jìn)行執(zhí)行??尚械淖龇ㄖ痪褪窃诿總€(gè)文件下載完的回調(diào)函數(shù)里去給一個(gè)全局變量加上此文件已加載完的標(biāo)記,同時(shí)判斷是否已經(jīng)全部加載完,完了就再按順序?qū)懭肽矰OM對(duì)象的innerHTML。

      或者弄個(gè)更高效更簡(jiǎn)潔的辦法:將合并這步操作放到服務(wù)器執(zhí)行,頁(yè)面只用請(qǐng)求一次:將a, b, c作為參數(shù)發(fā)給服務(wù)器。但它的壞處是不能緩存。

      ---------------------------------------
      不知道有多少人了解過(guò)騰訊一個(gè)類(lèi)似這樣功能的js....很好很強(qiáng)大的。。

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多