js文件引用方式及其同步執行與異步執行

詳見: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp74

 

任何以appendChild(scriptNode) 的方式引入的js文件都是異步執行的 (scriptNode 需要插入document中,只創建節點和設置 src 是不會加載 js 文件的,這跟 img 的與加載不同 )   
html文件中的<script>標籤中的代碼或src引用的js文件中的代碼是同步加載和執行的
html文件中的<script>標籤中的代碼使用document.write()方式引入的js文件是異步執行的
html文件中的<script>標籤src屬性所引用的js文件的代碼內再使用document.write()方式引入的js文件是同步執行的

1、

<script>

//同步加載執行的代碼

</script>

2、

<script src="xx.js"></script>  //同步加載執行xx.js中的代碼

3、

<script>

document.write('<script src="xx.js"><\/script>');   //異步加載執行xx.js中的代碼

</script>

4、

<script src="xx.js"></script>

xx.js中有下面代碼:

document.write('<script src="11.js"><\/script>');   

document.write('<script src="22.js"><\/script>');   

則xx.js和11.js、22.js 都是同步加載和執行的。

如果 xx.js 以插入方式異步加載,則 11.js 和 22.js 仍然是同步加載的(異步中的同步,即,這2個文件的加載是分先後次序的)

測試:在11中 alert, 22中 document.write() ,可以看到 22中寫入語句被阻塞

5、

下面這種方式,xx.js會在appendChild執行之後異步加載執行

var script = document.createElement("script");

script.setAttribute("src","xx.js");

documenrt.getElementsByTagName("head")[0].appendChild(script);

   

 

一個加載 js 文件的 函數:

var loadJS = function(url,callback){  var head = document.getElementsByTagName('head')[0],   script = document.createElement('script');    script.src = url;   script.type = "text/javascript";   head.appendChild( script);

   script.onload = script.onreadystatechange = function(){

//script 標籤,IE 下有 onreadystatechange 事件, w3c 標準有 onload 事件     

//這些 readyState 是針對IE8及以下的,W3C 標準因爲script 標籤沒有這個 onreadystatechange 所以也不會有 this.readyState , 

// 好在文件加載不成功 onload 不會執行,(!this.readyState) 是針對 W3C標準的

if ((!this.readyState) || this.readyState == "complete" || this.readyState == "loaded" ){ 

         callback();      }else{          alert("can not load the js file")      }   }}

 

對於第4點的測試(其中插入 alert 很容易看到加載時阻塞的)

tryjs.html

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script src="tryjs.js" 
οnlοad="if(!document.all){console.log('outer js callback, not IE');}" 
onreadystatechange="console.log('outer js callback ',this.readyState,' IE');"></script>


<body>

</body>
</html>

 

tryjs.js

console.log('write begin');
document.write('<script src="try.1.js" onreadystatechange="console.log(\'file 1 callback \',this.readyState,\' IE\');" οnlοad="if(!document.all){console.log(\'file 1 callback,NOT IE \');}"><\/script>');
document.write('<script src="try.2.js" onreadystatechange="console.log(\'file 2 callback \',this.readyState,\' IE\');" οnlοad="if(!document.all){console.log(\'file 2 callback,NOT IE \');}"><\/script>');
console.log('write finished');

try.1.js
console.log('loadjs 1 begin');
console.log('loadjs 1 finished');

 

try.2.js

console.log('loadjs 2 begin');
console.log('loadjs 2 finished');

 

測試結果(file 2 和 file 1 的 callback complete 在IE7\8\9次序不確定

IE 7:
日誌: outer js callback loading IE 
日誌: outer js callback loaded IE 
日誌: write begin 
日誌: write finished 
日誌: outer js callback complete IE 
日誌: file 1 callback loading IE 
日誌: file 2 callback loading IE 
日誌: loadjs 1 begin 
日誌: loadjs 1 finished 
日誌: loadjs 2 begin 
日誌: loadjs 2 finished 
日誌: file 2 callback complete IE 
日誌: file 1 callback complete IE 


IE8:
日誌: outer js callback loading IE 
日誌: outer js callback loaded IE 
日誌: write begin 
日誌: write finished 
日誌: outer js callback complete IE 
日誌: file 1 callback loading IE 
日誌: file 2 callback loading IE 
日誌: loadjs 1 begin 
日誌: loadjs 1 finished 
日誌: loadjs 2 begin 
日誌: loadjs 2 finished 
日誌: file 2 callback complete IE 
日誌: file 1 callback complete IE 

IE9:
日誌: write begin 
日誌: write finished 
日誌: outer js callback complete IE 
日誌: file 1 callback loading IE 
日誌: file 2 callback loading IE 
日誌: loadjs 1 begin 
日誌: loadjs 1 finished 
日誌: loadjs 2 begin 
日誌: loadjs 2 finished 
日誌: file 1 callback complete IE 
日誌: file 2 callback complete IE 



FIREFOX:
write begin 
write finished
outer js callback, not IE
loadjs 1 begin
loadjs 1 finished
file 1 callback,NOT IE
loadjs 2 begin
loadjs 2 finished
file 2 callback,NOT IE


CHROME:
write begin     
write finished    
outer js callback, not IE    
loadjs 1 begin    
loadjs 1 finished    
file 1 callback,NOT IE 
loadjs 2 begin    
loadjs 2 finished    
file 2 callback,NOT IE 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章