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