首頁  >  文章  >  web前端  >  javascript 檔案的同步載入與非同步載入實作原理_javascript技巧

javascript 檔案的同步載入與非同步載入實作原理_javascript技巧

WBOY
WBOY原創
2016-05-16 17:46:37975瀏覽
HTML 4.01 的script屬性
charset: 可選。指定src引入程式碼的字元集,大多數瀏覽器忽略該值。
defer: boolean, 可選。延遲腳本執行,相當於將script標籤放入頁面body標籤的底部,js腳本會在document的DOMContentLoaded之前執行。除IE和較新版本的Firefox外,其他瀏覽器並未支援。
language: 已廢棄。大部分瀏覽器會忽略該值。
src: 可選。指定引入的外部程式碼文件,不限制後綴名。
type: 必選。指定腳本的內容類型(MIME類型)。現實中通常不指定該值也可以,瀏覽器會預設當作text/javascript類型來解釋執行。

HTML5中的script屬性
script 標籤在HTML5中除了具備HTML5新標準定義的屬性以外,和HTML4.01相比移除了language屬性,修改了type屬性為可選的(預設text/javascript),並新增了一個屬性async。
async :boolean, 屬性的作用,定義腳本是否非同步執行,取值true或false。
如果 async 設為 true ,則會忽略 defer 屬性。
非同步執行的js 檔案被假定為不使用document.write() 向載入中的document 寫入內容,因此不要在非同步執行的js 檔案的載入執行過程中使用document.write()
除了script 標籤屬性外,頁面引入js 檔案的方式影響其載入執行方式:
任何以新增script 節點(例如appendChild(scriptNode) ) 的方式引入的js檔案都是異步執行的(scriptNode 需要插入document中,只創建節點和設定src 是不會載入js 檔案的,這跟img 的預先載入不能類比)
html檔案中的<script>標籤中的程式碼或src引用的js檔案中的程式碼是同步載入和執行的<BR>html檔案中的<script>標籤中的程式碼使用document.write()方式引入的js檔案是異步執行的<BR>html檔案中的<script>標籤src屬性所引用的js檔案的程式碼內再使用document.write()方式引入的js檔案是同步執行的<BR>使用Image 物件非同步預先載入js 檔案(不會被執行) <br><br>不要使用類似下面這種做法,這樣並不會發起載入js 檔案的請求: <BR>divNode.innerHTML = '<script src="xxx.js"></script>';
window.onload 事件會在js 檔案載入完畢才觸發(即使是非同步載入)
========================================== ===========
1、
<script> <BR>//同步載入執行的程式碼<BR></script>
2、
//同步載入執行xx.js中的程式碼
3、
<script> <BR>document.write('<script src="xx.js" ></script>'); //非同步載入執行xx.js中的程式碼

4、

xx.js中有下面程式碼:
複製程式碼 程式碼如下:

document.write ('');
document.write('');

則xx.js和11.js、22.js 都是同步載入和執行的。
如果xx.js 、11.js 和22.js 以插入script 節點方式異步加載,則11.js 和22.js 是異步加載的,
如果xx.js 以script 節點方式異步加載, 11.js 和22.js 以document.write(script) 方式加載,則11.js 和22.js 是同步加載的(經最新的瀏覽器測試, 在chrome 下,xx.j 異步加載執行已經無法使用document.write() 寫入文件內容給文件的,但是firefox 和IE 卻可以在document 關閉之前寫入(方法是在html 中alert阻止文件關閉))
測試:在11.js中alert()(不要用for 循環,瀏覽器是單執行緒執行的,持續執行任何一段程式碼都會導致其餘程式碼被阻塞) , 22.js 中console.log() ,可以看到22.js中的程式碼被阻塞
5.
下面這種方式,xx.js會在appendChild執行之後非同步載入執行
複製程式碼 程式碼如下:

var script = document.createElement("script");
script.setAttribute("src","xx.js");
documenrt.getElementsByTagName("headhead") [0].appendChild(script);

6、使用Image 物件非同步預先載入js 檔案(不會被執行)
Image 的src 被賦值時即發起請求,而且對檔案類型不挑剔(圖片也可能是有腳本動態建立的,例如驗證碼),因此可以將js 檔案的url 賦給image.src, js 載入之後被瀏覽器快取.
複製程式碼



複製程式碼



複製程式碼

程式碼如下:

var img = new Image(); img.onload = function(){ alert(1); } ; //由於傳回的js檔案MIME 不是圖片, onload回呼函數不會被觸發img.src = 'http://localhost/test/loadjs/try.2.js'; var s = document.createElement("script"); var h = document.getElementsByTagName("head")[0]; //執行js s.src=img.src;
h.appendChild(s);


一個載入js 檔案的函數:




複製程式碼


程式碼如下:



程式碼如下:


var loadJS = function(url,callback){
var head = document.getElementsByTagName('head');
if(head&&head.length){
head = head[0];
}else{
head = document.body;
}
var 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標準的, IE 9 也支援W3C標準的onload if ((!this.readyState) || this.readyState == "complete" || this.readyState == "loaded" ){
callback();
}
}//end onreadystatechange
}


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




複製程式碼


程式碼如下:
>





tryjs.js 程式碼如下:


console.log('write begin');
document.write('');
document.write('');
console.log( 'write finished');
try.1.js 複製程式碼


複製程式碼
複製程式碼複製程式碼複製程式碼 程式碼如下: console.log('loadjs 1 begin'); console.log('loadjs 1 finished'); try.2.js 複製程式碼 程式碼如下: console.log('loadolejs 2 begin'); conscons .log('loadjs 2 finished');
測試結果(file 2 和file 1 的callback complete 在IE789次序不確定)
IE 7:
日誌: outer js callback loading IE
日誌: outer js callback : write begin
日誌: write finished
日誌: outer js callback complete IE
日誌: file 1 callback loading IE
日誌: file 2 callback loading IE
IEd >日誌: loadjs 1 finished
日誌: loadjs 2 begin
日誌: loadjs 2 finished
日誌: file 2 callback complete IE
日誌: file 1 callback completeback
日誌: outer js callback loading IE
日誌: outer js callback loaded IE
日誌: write begin
日誌: write finished
file: outer js 1 callback loading IE
日誌: file 2 callback loading IE
日誌: loadjs 1 begin
日誌: loadjs 1 finished
日誌: loadjs 2 begin
日誌: load : file 2 callback complete IE
日誌: file 1 callback complete IE

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

FIREFOX:
write begin
write finished loadjs 1 finished
file 1 callback,NOT IE
loadjs 2 begin
loadjs 2 finished
file 2 callback,NOT IE write begin
write finished
outer js callback, not IE
loadjs 1 begin
loadjs 1 finished
file 1 callback,NOT IE
load 🎜>file 2 callback,NOT IE
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn