JS 動態載入指令碼 執行回調

來源:互聯網
上載者:User

標籤:

JS 動態載入指令碼  執行回調

關於在javascript裡面載入其它的js檔案的問題可能很多人都遇到過,但很多朋友可能並不知道怎麼判斷我們要載入的js檔案是否載入完成,如果沒有載入完成我們就調用檔案裡面的函數是不會成功的。本文講解怎麼在js中載入其它js檔案並在載入完成後執行回呼函數。

我們可以動態建立 <script> 元素,然後通過更改它的 src 屬性來載入指令碼,但是怎麼知道這個指令檔載入完成了呢,因為我們有些函數需要在指令碼載入完成生效後才能開始執行。 經過對網路上資源的搜尋,我發現在 IE 瀏覽器中可以使用 <script> 元素的 onreadystatechange 來監控載入狀態的改變,並通過判斷它的 readyState 是 loaded 或 complete 來判斷指令碼是否載入完成。而非 IE 瀏覽器可以使用 onload 來直接判斷指令碼是否載入完成。

一個簡單的實現過程看上去是下面這樣的:

//IE下:var script = document.createElement("script");script.setAttribute("type","text/javascript");script.onreadystatechange = function() {    if(this.readyState == "loaded" || this.readyState == "complete"){        alert("載入成功啦!");    }}script.setAttribute("src",scripts[i]);//Opera、FF、Chrome等:var script = document.createElement("script");script.setAttribute("type","text/javascript");script.onload = function() {    alert("載入成功啦!");}script.setAttribute("src",scripts[i]); 

原理很簡單,根據這兩個簡單的原理,我們進行一些修改,我把改成了兩個函數,分別是串列載入和並行載入指令碼。 

 

當傳一個包含多個JS檔案路徑的數組時,串列載入函數從第一個指令檔載入開始,每載入成功一個便開始載入下一個指令檔,全部載入完成後執行回呼函數。而並行載入是一開始便載入全部的指令檔,也就是他們從同一點開始載入,當全部載入完成後,執行回呼函數。

經過測試,這兩個函數相容目前的所有主流瀏覽器。

/**  * 串聯載入指定的指令碼 * 串聯載入[非同步]逐個載入,每個載入完成後載入下一個 * 全部載入完成後執行回調 * @param array|string 指定的指令碼們 * @param function 成功後回調的函數 * @return array 所有產生的指令碼元素對象數組 */function seriesLoadScripts(scripts,callback) {   if(typeof(scripts) != "object") var scripts = [scripts];   var HEAD = document.getElementsByTagName("head").item(0) || document.documentElement;   var s = new Array(), last = scripts.length - 1, recursiveLoad = function(i) {  //遞迴       s[i] = document.createElement("script");       s[i].setAttribute("type","text/javascript");       s[i].onload = s[i].onreadystatechange = function() { //Attach handlers for all browsers           if(!/*@[email protected]*/0 || this.readyState == "loaded" || this.readyState == "complete") {               this.onload = this.onreadystatechange = null; this.parentNode.removeChild(this);                if(i != last) recursiveLoad(i + 1); else if(typeof(callback) == "function") callback();           }       }       s[i].setAttribute("src",scripts[i]);       HEAD.appendChild(s[i]);   };   recursiveLoad(0);} /** * 並聯載入指定的指令碼 * 並聯載入[同步]同時載入,不管上個是否載入完成,直接載入全部 * 全部載入完成後執行回調 * @param array|string 指定的指令碼們 * @param function 成功後回調的函數 * @return array 所有產生的指令碼元素對象數組 */ function parallelLoadScripts(scripts,callback) {   if(typeof(scripts) != "object") var scripts = [scripts];   var HEAD = document.getElementsByTagName("head").item(0) || document.documentElement, s = new Array(), loaded = 0;   for(var i=0; i<scripts.length; i++) {       s[i] = document.createElement("script");       s[i].setAttribute("type","text/javascript");       s[i].onload = s[i].onreadystatechange = function() { //Attach handlers for all browsers           if(!/*@[email protected]*/0 || this.readyState == "loaded" || this.readyState == "complete") {               loaded++;               this.onload = this.onreadystatechange = null; this.parentNode.removeChild(this);                if(loaded == scripts.length && typeof(callback) == "function") callback();           }       };       s[i].setAttribute("src",scripts[i]);       HEAD.appendChild(s[i]);   }}

在這裡是把 <script> 標籤動態插入到頁面中的 <head> 標籤內部,並且載入完成後標籤元素會被自動移除。 細心的你還會發現,這裡使用了一種稱作條件編譯的方法作為運算式(!/*@[email protected]*/0)來判斷是否非 IE 瀏覽器,關於條件編譯並不是本文的重點,有興趣的您可以上網尋找相關資料進行學習。

這兩個函數的使用方法: 這裡我們聲明了一個陣列變數,裡麵包含了兩個遠端JS檔案地址(當然 <script> 標籤呼叫指令碼是支援跨域的):

var scripts = [      "http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js",    "http://wellstyled.com/files/jquery.debug/jquery.debug.js"];//這兩個檔案分別是 jQuery 1.4.的庫檔案和 jQuery Debug 外掛程式//然後你可以使用下面的方法調用並在成功後執行回調了。seriesLoadScripts(scripts,function(){     /*   debug = new $.debug({         posTo : { x:‘right‘, y:‘bottom‘ },       width: ‘480px‘,       height: ‘50%‘,       itemDivider : ‘<hr>‘,       listDOM : ‘all‘   });     */   alert(‘指令碼載入完成啦‘);}); 

這裡使用的是串聯載入的函數,當然你也可以使用並聯載入函數,這可以根據情況使用,建議每下一個指令碼對上一個指令碼有依賴性的使用串聯載入,否則使用並聯,因為原理上並聯要比串聯快那麼些。

JS 動態載入指令碼 執行回調

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.