最近在寫一個Javascript的框架,剛把DOMContentLoaded事件封裝好,略帶小興奮,把開發過程中遇到的原理和兼容性問題做篇筆記,省的忘記到處找。
我們在寫js程式碼的時候,通常都會加入window.onload事件,主要是為了在DOM載入完後可以使用getElementById,getElementsByTagName等方法選取DOM元素進行操作,但是window.load會等到載入完DOM、腳本、CSS,最後加載完圖片甚至是iframe中的所有資源才會觸發,很多時候網頁的圖片較多較大,要等最後圖片這個耗時大戶加載完才執行js明顯有些太遲了,很多時候都會影響使用者體驗。
很多js框架都有個document.ready的功能,像JQuery的$(document).ready()方法,可以在DOM載入完就立即執行js程式碼,讓圖片自個慢慢載入吧。
document.ready的核心是DOMContentLoaded事件,firefox、chrome、opera、safari、ie9 都可以使用addEventListener('DOMContentLoaded',fn,false)進行事件綁定,而ie6~8不支援DOMContentLoaded事件,所以要針對ie6~8做相容性處理。
資料上說ie6~8可以使用document.onreadystatechange事件監聽document.readyState狀態是否等於complete來判斷DOM是否載入完畢,如果頁面中嵌有iframe的話,ie6~8的document.readyState會等到iframe中的所有資源載入完才會變成complete,此時iframe變成了耗時大戶。但經過測試,即使頁面中沒有iframe,當readyState等於complete時,實際觸發的是onload事件而不是DOMContentLoaded事件,對這點表示驚奇。
還好ie有個特有的doScroll方法,當頁面DOM未載入完成時,呼叫doScroll方法時,就會報錯,反過來,只要一直間隔呼叫doScroll直到不報錯,那就表示頁面DOM載入完畢了,不管圖片和iframe中的內容是否加載完畢,此法都有效。
如果有多個js檔案綁定了document.ready事件,為了防止瀏覽器重複綁定,同時有序執行,可以引入一個事件佇列機制來解決。
以上就是document.ready事件的原理和相容性問題,下面貼段實例程式碼,為了方便理解執行過程,使用函數封裝的模式,執行過程都寫在註解裡了,如果有不妥之處歡迎指教。