DOMContentLoaded
當初始的 HTML 文檔被完全加載和解析完成之后,DOMContentLoaded 事件被觸發(fā),而無需等待樣式表、圖像和子框架的完成加載?!?MDN
雖然兩者經(jīng)常被拿來比較,但是兩者在事件對象上就有很大的不同。DOMContentLoaded是 document 對象的觸發(fā)事件,document常用的事件還有readyStateChange ;而 load 是 window 對象的事件,與它同屬于window 對象的常用事件有:
- abort,用戶放棄下載時觸發(fā)
- beforeprint/afterprint,打印前后觸發(fā)
- beforeunload,頁面即將取消加載時觸發(fā)
- blur,元素失去聚焦的時候觸發(fā)
- storage,當localStorage 或者sessionStorage發(fā)生改變時觸發(fā)
- unload ,當頁面消失的時候觸發(fā)。
通過查閱標準
我們知道,DOMContentLoaded 事件在觸發(fā)之前
- 有一次 readyState 的變化,從 loading 到 interacitve。
- 所有節(jié)點從棧里彈出。
- 將靜態(tài)的script執(zhí)行完畢,動態(tài)script不會阻塞DOMContentLoaded 事件的觸發(fā)。
- 然后就是觸發(fā) DOMContentLoaded 事件。
實驗一
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Event Demo</title>
</head>
<body>
<p class="demo">hello</p>
<script>
console.log("script excuting, state is "+ document.readyState);
</script>
<script>
setTimeout(function() {
document.querySelector(".demo").style.color = "red";
console.log("element painting and the state is "+document.readyState);
},2000)
</script>
</body>
</html>
// js file
document.addEventListener("DOMContentLoaded", function (){
console.log("DOMContentLoaded event");
});
document.addEventListener("readystatechange", function (){
console.log("state change: now is: "+document.readyState);
});
// output
"script excuting, state is loading"
"state change: now is: interactive"
"DOMContentLoaded event"
"state change: now is: complete"
"element painting and the state is complete"
從實驗可以看出:
- 在觸發(fā)DOMContentLoaded 事件之前,readystatechange 事件被觸發(fā)了一次,readyState 從loading 變到 interactive,DOMContentLoaded 觸發(fā)后有觸發(fā)了一次 readystatechange,readyStat 變成 complete。
- DOMContentLoaded 在靜態(tài)腳本執(zhí)行完畢之后(
script excuting)才會觸發(fā)。而動態(tài)的腳本(element painting)并不會阻礙DOMContentLoaded 事件的觸發(fā)。
load
根據(jù)標準,load事件是在readyState 為complete之后才會觸發(fā),我們需要實踐一下,在上方js file的代碼基礎(chǔ)上加入:
window.addEventListener("load",function() {
console.log("load event");
});
將它放到先前代碼前面,可以得到一下輸出:
"script excuting, state is loading"
"state change: now is: interactive"
"DOMContentLoaded event"
"state change: now is: complete"
"load event"
"element painting and the state is complete"
也就是說,在readyState狀態(tài)為complete之后,才會觸發(fā)load事件,然后才會執(zhí)行到動態(tài)的script腳本。
從以上實驗可以總結(jié),readyState:loading -> 靜態(tài)script 執(zhí)行 -> readystatechange:interacitve -> DOMContentLoaded -> readystatechange:complete -> load -> 動態(tài)script
參考閱讀
- whatwg.org, parsing.html#the-end
- AlloyTeam, JS、CSS以及img對DOMContentLoaded事件的影響