摘要:完成文檔和所有子資源已完成加載。在中可以使用事件來(lái)檢測(cè)文檔是否加載完畢在更早的版本中可以通過(guò)每隔一段時(shí)間執(zhí)行一次來(lái)檢測(cè)這一狀態(tài),因?yàn)檫@條代碼在加載完畢之前執(zhí)行時(shí)會(huì)拋出錯(cuò)誤。
Document.readyState
Document.readyState 屬性描述了文檔的加載狀態(tài)。當(dāng)readyState的值變化時(shí),document對(duì)象上的readystatechange事件將被觸發(fā)。
readyState有三類(lèi)值:
loading / 加載:document 仍在加載。
interactive / 互動(dòng):文檔已經(jīng)完成加載,文檔已被解析,但是諸如圖像,樣式表和框架之類(lèi)的子資源仍在加載。
complete / 完成:文檔和所有子資源已完成加載。這個(gè)狀態(tài)表示 load 事件即將被觸發(fā)。
// 模擬 DOMContentLoaded/ jquery ready document.onreadystatechange = function () { if (document.readyState === "interactive") { initApplication(); } } // 模擬 load/onload 事件 document.onreadystatechange = function () { if (document.readyState === "complete") { initApplication(); } }DOMContentLoaded
當(dāng)初始HTML文檔被完全加載和解析完成之后,DOMContentLoaded 事件被觸發(fā),而無(wú)需等待樣式表、圖像和子框架完成加載。
DOMContentLoaded支持IE9及以上。在IE8中,可以使用readystatechange事件來(lái)檢測(cè)DOM文檔是否加載完畢.在更早的IE版本中,可以通過(guò)每隔一段時(shí)間執(zhí)行一次document.documentElement.doScroll("left")來(lái)檢測(cè)這一狀態(tài),因?yàn)檫@條代碼在DOM加載完畢之前執(zhí)行時(shí)會(huì)拋出錯(cuò)誤(throw an error)。
瀏覽器向服務(wù)器請(qǐng)求到了 HTML 文檔后便開(kāi)始解析,產(chǎn)物是 DOM(文檔對(duì)象模型),到這里 HTML 文檔就被加載和解析完成了。
當(dāng)文檔中沒(méi)有腳本時(shí),瀏覽器解析完文檔便能觸發(fā) DOMContentLoaded 事件;如果文檔中包含腳本,則腳本會(huì)阻塞文檔的解析,而腳本需要等 CSSOM 構(gòu)建完成才能執(zhí)行(因?yàn)槟_本可能在文檔的解析過(guò)程中請(qǐng)求樣式信息,如果樣式還沒(méi)有加載和解析,腳本將得到錯(cuò)誤的值。Firefox在存在樣式表還在加載和解析時(shí)阻塞所有的腳本,而chrome只在當(dāng)腳本試圖訪問(wèn)某些可能被未加載的樣式表所影響的特定的樣式屬性時(shí)才阻塞這些腳本。詳見(jiàn))。在任何情況下,DOMContentLoaded 的觸發(fā)都不需要等待圖片等其他資源加載完成。
defer 和 async這兩個(gè)屬性都對(duì)于內(nèi)聯(lián)腳本無(wú)作用 (即沒(méi)有src屬性的腳本)。
async:指示瀏覽器是否在允許的情況下異步執(zhí)行該腳本。HTML5屬性。
defer:被設(shè)定用來(lái)通知瀏覽器該腳本將在文檔完成解析后,觸發(fā) DOMContentLoaded 事件前執(zhí)行。
區(qū)別同步腳本:
當(dāng) HTML 文檔被解析時(shí)如果遇見(jiàn)(同步)腳本,則停止解析,先去加載腳本,然后執(zhí)行,執(zhí)行結(jié)束后繼續(xù)解析 HTML 文檔。過(guò)程如下圖:
帶defer :
當(dāng) HTML 文檔被解析時(shí)如果遇見(jiàn) defer 腳本,則在后臺(tái)加載腳本,文檔解析過(guò)程不中斷,而等文檔解析結(jié)束之后,defer 腳本執(zhí)行。如果有多個(gè)defer腳本,會(huì)按照它們?cè)陧?yè)面出現(xiàn)的順序加載。過(guò)程如下圖:
帶async :
當(dāng) HTML 文檔被解析時(shí)如果遇見(jiàn) async 腳本,則在后臺(tái)加載腳本,文檔解析過(guò)程不中斷。腳本加載完成后,文檔停止解析,腳本執(zhí)行,執(zhí)行結(jié)束后文檔繼續(xù)解析。因?yàn)橛?async 的情況下,JavaScript 腳本一旦下載好了就會(huì)執(zhí)行,所以多個(gè)async腳本是不能保證加載順序的。過(guò)程如下圖:
defer、async與DOMContentLoaded 的執(zhí)行順序如果 script 標(biāo)簽中包含 defer,在 DOM、CSSOM 構(gòu)建完畢,defer 腳本執(zhí)行完成之后,DOMContentLoaded 事件觸發(fā)。
如果 script 標(biāo)簽中包含 async,HTML文檔解析完畢,DOMContentLoaded 事件觸發(fā),async 腳本是否執(zhí)行完畢對(duì)其無(wú)影響。
參考自:
readyState
DOMContentLoaded