15

我一直在實施yepnope腳本加載器作爲modernizr.js庫的一部分。之後,我成功地獲得了jQuery以加載和jQuery相關的腳本。我是異步加載資源的新手,所以對我來說有些新意。我一直在四處尋找,但對以下事項沒有多少好運。

我的問題是如何在使用yepnope.js框架時如何有效替換$(document).ready()的功能。

我的理論是在我的基礎庫中創建一個適當命名的函數,然後在我的頁面上將該變量設置爲包含我現有的$(document).ready()代碼的匿名函數。在所有腳本加載完整回調後,該變量將由yepnope調用。

你是否同意這是一個很好的做法,或者我完全用錯誤的方式來對待它? (對於那些不知道,yepnope.js的異步性質意味着文檔在yepnope加載器完成之前調用$或jQuery,拋出一個「$ is undefined」的錯誤< - 請糾正我,如果這是錯誤的。)

第一個問題,希望它是一個很好的問題。

+0

如果只想澄清一下,我是整合這與很多現有的js文件的適用於單個頁面的網站,依賴的document.ready()。也許這是錯誤的做法 - 我想聽聽你的意見。 – 2011-04-15 08:28:16

回答

11

如果在沒有yepnope的情況下加載jQuery對您來說不是問題,那麼有一個更簡單的方法。

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> 

<script> 
    $.holdReady(true); 

    yepnope.load({ 
     load: [ 
      'placeholder.js', 
      'jquery-ui.min.js' 
     ], 
     complete: function(){ 
      $.holdReady(false); 
     } 
    }); 
</script> 
+0

謝謝!我不知道jQuery有這個功能。更簡單,更優雅的解決方案。 – 2012-06-04 16:13:42

+0

我把$(document).ready();在這下面?它需要在它的單獨'

1

腳本標記加載同步 - 所以,如果你把你的yepnope在一個js文件,並通過腳本標籤加載它:

<script type="text/javascript" src="/my-yepnope-stuff.js"></script> 
</body> 

權利之前,你可以肯定的結束標記是在$(文件).ready()狀態。

你需要自己回答的是強制yepnope以$(document).ready()的方式加載是否有意義,因爲它的主要目的是在第一個中斷腳本標記的同步加載順序地點。

+0

我的問題是,在某些情況下,我必須測試文檔,因爲我使用第三方控件庫(telerik)。如果找不到控件(即尚未加載),它們的函數將返回空值。除此之外,我想努力加載異步腳本。 – 2011-04-18 09:47:30

0

使用@ezmilhouse的指導,我想到了在保持與舊代碼的兼容性的同時實現我所追求的最佳方式。

我的解決方案是設置我的yepnope scriptloader,以基於它們各自的依賴關係以分層方式加載所有必需的腳本。一旦加載了所有腳本,您就可以使用我呼叫的complete屬性來調用我的ready函數。這意味着文檔已經準備就緒,代碼將無任何問題。

我也動了我的js到我的網頁的基礎(的東西,我應該在很久以前做過,但我們有很多傳統的網頁!:))

下面是一個例子(使用假僅供說明之用)libray /腳本名稱:

yepnope({ 
    test: baseLib.debug, 
    yep: { "max": "/version2/res/jquery/jquery-1.5.2.js" }, 
    nope: { "min": "/version2/res/jquery/jquery-1.5.2.min.js" }, 
    callback: { 
     "max": function (url, result, key) { 
      baseLib.Log("jQuery full loaded."); 
     }, 
     "min": function (url, result, key) { 
      baseLib.Log("jQuery min loaded."); 
     } 
    }, 
    complete: function() { 
     if (window.$) { 
      yepnope({ 
       test: base.debug, 
       yep: { 
        "anotherscript": "script/url/here.js", 
        "anotherscript2": "script/url/here2.js" 
       }, 
       nope: { 
        "anotherscript": "script/url/here-min.js", 
        "anotherscript2": "script/url/here2-min.js" 
       }, 
       both: { 
        "anotherscript3": "script/url/here3.js" 
       }, 
       callback: { 
        "anotherscript": function (url, result, key) { 
         baseLib.Log("anotherscript " + (result ? "Max" : "Min") + " loaded."); 

        }, 
        "anotherscript2": function (url, result, key) { 
         baseLib.Log("anotherscript2 " + (result ? "Max" : "Min") + " loaded."); 
        }, 
        "anotherscript3": function (url, result, key) { 
         baseLib.Log("anotherscript3 loaded."); 
        } 
       }, 
       complete: function() { 
        baseLib.Log("Scripts Loaded"); 
        baseLib.Page.Ready(); 
       } 
      }); 

     } 
     else { 
      baseLib.Log("Could not load jQuery. No further jQuery dependent files loaded.", "error"); 
     } 
    } 
}); 

在我的網頁的JS,我將一個功能分配給baseLib.Page.Ready然後將由yepnope上完全被調用。

11

這是我使用的技術。它允許我隨心所欲地灑$(document).ready()風格的調用。使用這種方法,您可以使用已經使用jQuery並具有$(document).ready()調用的站點,並輕鬆改造yepnope。

首先,在任何調用$(document)的javascript之前,添加這行JS,最好在文檔頭中。準備():

<script> 
    var docready=[],$=function(o){function r(fn){docready.push(fn);}if(typeof o === 'function') r(o);return{ready: r}}; 
</script> 

然後,有你yepnope jQuery的測試對象設置與此類似:

yepnope({ 
    load: '//ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js', 
    complete: function() { 
     $ = jQuery;   
     for(n in docready) $(document).ready(docready[n]); 
    } 
}); 

我們創建一個假的$(document)。就緒()的jQuery加載之前。這將每個$(document).ready()調用存儲在一個數組docready中。然後,一旦jQuery加載完成,我們用現在加載的真正的jQuery對象覆蓋我們的臨時$對象。然後,我們遍歷所有存儲的$(document).ready()調用,然後執行它們。

更新:來自Chris Jones的改進版本也包含$(function(){})風格的調用。

+0

嗨,我使用了你描述的方法,並且在關閉body標籤之前放置yepnope,每件事情都很好。但是:我之前在某處加載了jquery.min.js,所以使用這個方法會再次加載一個不必要的jquery?問候安德烈 – cwhisperer 2012-04-26 08:07:07

+0

嗨安德烈 - 如果你已經嘗試加載jQuery預先,你可以 1)從yepnope刪除調用加載jquery,只是留下你的其他腳本2)改變加載jQuery的yepnope塊爲: test:typeof jQuery =='undefined', yep:'//ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js', complete:function(){ $ = jQuery的; (docready)$(document).ready(docready [n]); } } 3)刪除先前的jQuery同步加載,並在$(document).ready(function(){...})塊中包裝所有使用jQuery的調用。 – Sc0ttyD 2012-04-26 13:14:32

+1

很好的解決方案。我一定會嘗試它。但是,在這種情況下如何處理通過JQuery.fn或$ .fn註冊的JQuery插件?後者是我認爲最糟糕的,因爲這些註冊會成功,並在事後被覆蓋;)...或者我在這裏錯過了一些關於插件使他們仍然像預期的一樣工作? – DotBert 2012-12-19 11:07:00

0

我認爲亞歷克斯·塞克斯頓solution是正確的:

yepnope({ 
    load: '//ajax.googleapisOFFLINE.com/ajaxX/libs/jquery/1.7.1/jquery.min.js', 
    callback: function() { 
     if (!window.jQuery) { 
      yepnope('/js/jquery-1.7.1.min.js'); 
     } 
    }, 
    complete: function() { 
     $(function(){ 
     $("div.whatever").css("color","red"); 
     }); 
    } 
}); 
相關問題