當我們剛學js的時候,應該就知道js是單線程,進行的是同步加載,會阻斷html 和css 的載入線(因為js能夠修改html 和css)
js同步載入的缺點:載入工具方法沒必要阻塞文檔,過得js載入會影響頁面效率,一旦網速不好,那麼整個網站將等待js載入而不進行後續的渲染等工作。
js裡面有些工具方法需要按需加載,用到加載,不用不加載? ? ?這時候就需要我們異步載入js。
JavaScript非同步載入的三種方案。
1、defer非同步加載,但要等到dom文件全部解析完才會執行。只有IE能用,也可以將程式碼全部寫到內部
<script type = "text/javascript" src = "tools.js" defer = "defer"></script>
<script defer = "defer"> console.log("a"); </script>
2、async 非同步加載,加載完就執行,async只能載入外部腳本,不能把js寫在script標籤裡
<script type = "text/javascript" aysnc = "aysnc"></script>
以上兩種方法執行時也不阻塞頁面
為了解決瀏覽器相容問題? ?如果1,2,兩種方法同時加載,會導致程式碼重疊覆蓋執行順序的衝突,所以引入第三種方法通用的方法
3、創建script,插入到DOM中,加載完畢後callBack ,
var script = document.createElement('script'); script.type = "text/javescript"; script.src = "demo.js"; // 此时就会加载src地址里面的东西 // 此时会有一个灯塔模式,灯塔模式会产生一个img属性,用来存放地址的加载 document.head.appendChild(script); //----此时就会在页面上展示js里面的内容
當我們在外部js檔案裡面寫一個test函數
var script = document.createElement('script'); script.type = "text/javascript"; script.src = "demo.js"; test(); document.head.appendChild(script);
這裡外部demo.js檔案就不展示了,裡面有一個test函數。結果如下:
test函數執行的時候因為載入需要時間,當test執行時,還沒載入完。所以會顯示test未定義。我們改如何解決這個問題呢?
首先我們就會想到onload事件。
script.onload : 相容性特別好,Safari chrome firefox opera都相容 ;
script.onload = function(){ test(); }
但是呢 IE 就script沒有onload事件,IE人家有自己的方法:script.readyState。
script.readyState : IE 的script上方有個狀態碼(readyState),透過狀態碼的校驗判斷是否已載入完成。在IE裡script標籤有readyStatechange事件,這個事件監聽的是,當script.readyState值變化的時候觸發事件。
(script.readyState == "complete" || script.readyState =="loaded" 表示解析完畢。)
script.onreadystatechange = function(){ if(script.readyState == "complete" || script.readyState == "loaded"){ callback(); //回调函数:当满足一定条件才可以被执行 } }
最後我們封裝函數,實現我們按需載入的功能。
function loadScript(url,callback){ var script = document.createElement('script'); script.type = "text/javascript"; if(script.readyState){ script.onreadyStatechange = function(){ if (script.readyState == "loaded" || script.readyState == "complete") { obj[callback](); } } }else{ script.onload = function(){ obj[callback](); } } script.src = url; document.head.appendChild(script); } loadScript('demo.js','test');
相關推薦:
以上是JavaScript單線程異步加載的三種方案的詳細內容。更多資訊請關注PHP中文網其他相關文章!