一枪孩、看文檔:
window.onload | document.onDOMContentLoaded | |
---|---|---|
描述 | 當(dāng)一個資源及其依賴資源已完成加載時,將觸發(fā)load事件偎箫。 | 當(dāng)初始的 HTML 文檔被完全加載和解析完成之后,DOMContentLoaded 事件被觸發(fā)皆串,而無需等待樣式表淹办、圖像和子框架的完成加載。 |
常規(guī)-規(guī)范 | DOM L3 | HTML5 |
常規(guī)-接口 | UIEvent | Event |
常規(guī)-是否冒泡 | 否 | 是 |
常規(guī)-能否被取消 | 否 | 能 (盡管一個簡單的事件被指定為不可取消) |
目標(biāo) | window | document |
默認(rèn)行為 | 無 | 無 |
屬性 | target type bubbles cancelable view detail | target type bubbles cancelable |
二恶复、實驗
一個簡單的DEMO:測試onload/onDOMContentLoaded
實驗設(shè)計:
給一個HTML文檔中加載css怜森、js、和img元素谤牡,給每個資源加上一個onload事件副硅,以此判斷這些資源是在何時加載完成的。-
實驗過程:
實驗1:
- 文件內(nèi)順序:css - script.scope - script - img - iframe翅萤。
- 輸出:
"font-awesome was loaded."
"jquery was loaded."
"bootstrap was loaded."
"DOM fully loaded and parsed"
"image was loaded."
"baidu was loaded."
"All resources finished loading!"可以看到恐疲,DOMContentLoaded事件會在文檔內(nèi)部的img和iframe加載完成之前就觸發(fā)了。因為這一事件只涉及初始的HTML文件的信息套么,而不涉及外部依賴培己。
- Tips:如果已有css文件的緩存,刷新時css也有可能會在DOMContentLoaded事件后面才出現(xiàn)胚泌。但是script一定會在之前出現(xiàn)省咨,哪怕使用了scope / defer屬性。
實驗2:
- 異步加載腳本:分別使用scope/defer/createElement方式加載新腳本玷室。
- 輸出:
"newscript was loaded."
"error"
"TypeError: Cannot read property 'appendChild' of null
at <anonymous>:14:21
at http://js.jirengu.com/js/prod/runner-3.25.5.min.js:1:13840
at http://js.jirengu.com/js/prod/runner-3.25.5.min.js:1:10893"
"jquery was loaded."
"bootstrap was loaded."
"DOM fully loaded and parsed"
"font-awesome was loaded."
"image was loaded."
"baidu was loaded."
"All resources finished loading!"可以看到零蓉,使用scope/defer方法異步加載的腳本依然會在onDOMContentLoaded觸發(fā)前完成笤受;但是createElement方式加載的腳本,雖然加載時間還是在onDOMContentLoaded之前壁公,但卻無法直接加到文檔中感论。這是因為后面的appendChild是一個DOM操作,而此時DOM樹還沒有渲染完成紊册,找不到對應(yīng)元素。
appendChild至少要在onDOMContentLoaded觸發(fā)后才能進(jìn)行快耿。實驗3:
- 給iframe一個非法地址囊陡。
- 輸出:
DOM fully loaded and parsed
// 很長很長時間……
"baidu was loaded."
"All resources finished loading!"可以看到,樣式表掀亥、圖像和子框架資源請求無響應(yīng)時會阻塞window.onload事件撞反,但不會影響document.onDOMContentLoaded事件。因為onDOMContentLoaded只考慮初始的HTML文檔搪花。
結(jié)論:
- onload事件是DOM事件遏片,onDOMContentLoaded是HTML5事件。
- onload事件會被樣式表撮竿、圖像和子框架阻塞吮便,而onDOMContentLoaded不會。
- 當(dāng)加載的腳本內(nèi)容并不包含立即執(zhí)行DOM操作時幢踏,使用onDOMContentLoaded事件是個更好的選擇髓需,會比onload事件執(zhí)行時間更早。