如何動態加載js?


第三方的js文件,自己寫的js文件,js越來越多了怎么辦?

 

提出問題:

1、js文件太多了,每個頁面都寫<script src="...">太麻煩。

2、如果路徑變化了,或者js名稱變化了怎么辦?每個頁面都改一遍嗎?

3、如何約束js文件的加載順序?a.js定義了一個函數,b.js要調用,但是b.js先加載了,a.js還沒加載完成,造成函數未定義,無法調用。

4、js文件的合並。開發階段,js會分成多個文件,這樣便於開發。但是成熟了之后會合並成一個文件。這樣引用方式就會變化,原先引用一堆js,現在只需要引用一個js。同樣不能每個頁面都改一遍。

5、加載js完畢之后,要可以執行回調函數。 

 

解決問題:

如何解決這些問題呢?我想到的辦法是——動態加載js。就是通過js代碼的方式來加載。

在網上找了一些資料,最后確定借鑒 張經緯 的代碼 http://www.zhangjingwei.com/archives/asynchronous-loading-js/

其中這段代碼挺符合我的需求。

var loadscript =
{
    $$:function(id){return document.getElementById(id)},
    tag:function(element){return document.getElementsByTagName(element)},
    ce:function(element){return document.createElement(element)},
    js:function(url,callback)
    {
        s = loadscript.ce('script');
        s.type = "text/javascript";
        s.onreadystatechange = ready;
        s.onerror = s.onload = callback;
        s.src = url;
        loadscript.tag('head')[0].appendChild(s);
        function ready(){
            if (s.readyState == 'loaded' || s.readyState == 'complete') {
                callback();
            }
        };
    }
}

 

一開始把代碼copy過來使用,在ie8和chrome里面都沒有問題。既然沒有問題那就用唄,雖然還不知道為啥要這么寫代碼。

 

遇到新問題:

但是沒過多久就遇到了問題,在IE10里面,樹、分頁、表格等,都會多出來好幾份?

把IE10設置為兼容IE7的模式,就一切正常。看了是IE10的新特性照成的。那么到底是怎么回事呢?斷點跟蹤吧。

 

弄了好久才發現,原來是js文件會被加載多次。

為什么被加載了多次呢?原因在於 onreadystatechange 和 onload 。為什么這兩個事件都調用了callback?為什么其他瀏覽器沒事,IE10有事呢?

根據斷點跟蹤得到了原因。

原來 chrome只會觸發 onload, 而不會觸發onreadystatechange(不會進入斷點)。

而IE7只會觸發 onreadystatechange,而不會觸發onload。

那么IE10呢?兩個都會被觸發。

 

繼續解決:

一開始是想做一個標志位。做一個標志,如果callback了就不再次callback。但是實際效果有點不穩定,當然很可能是俺代碼沒處理好。

於是還是換一種方法吧。老辦法,判斷瀏覽器類型。

如果是IE10,那么只設置onload。然后,世界安靜了。當然這里瀏覽器的類型判斷還不完全。瀏覽器太多了,遇到不兼容的在考慮吧,俺js其實很爛的。

 

var loadscript =
{
    $$: function(id) { return document.getElementById(id); },
    tag: function(element) { return document.getElementsByTagName(element); },
    ce: function(element) { return document.createElement(element); },
    js: function(url, callback) {
        var s = loadscript.ce('script');
        s.type = "text/javascript";
        s.src = url;
        if (document.documentMode == 10 || document.documentMode == 9) {
            s.onerror = s.onload = loaded;
        } else {
            s.onreadystatechange = ready;
            s.onerror = s.onload = loaded;
        }
        loadscript.tag('head')[0].appendChild(s);

        function ready() { /*IE7.0/IE10.0*/
            if (s.readyState == 'loaded' || s.readyState == 'complete') {
                callback();
            }
        }

        function loaded() { /*chrome/IE10.0*/
            callback();
        }
    }
};

 

 

小結:

看最后的代碼,是沒啥特別的,重點在於理解原有代碼,發現問題,解決問題的過程。

 

下一步是如何管理js。還有js的客戶端緩存、復用的問題。

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM