onload和DOMContentLoaded事件

1. onload 事件

​在頁面的所有資源加載完成時,window對象上會觸發一個onload事件。此時頁面的DOM樹已經構建完成,並且完成了所有圖片、樣式表、腳本等資源也已經加載完成。但是存在的問題是,當資源過多過大時,onload會出現比較嚴重的延遲問題,嚴重影響用戶體驗。

2. DOMContentLoaded 事件

對比onload事件,DOMContentLoaded事件就更加合理,該方法觸發的時間較早。它在DOM內容加載完後就觸發,無需等待其他資源的加載完成。

window.onload = function() {
    console.log('onload');
};
document.addEventListener('DOMContentLoaded', function() {
    console.log('DOMContentLoaded');
});

上述代碼的執行結果爲依次打印出:DOMContentLoaded和onload。

但IE仍不支持DOMContentLoaded。

3. onreadystatechange 事件

雖然IE不支持DOMContentLoaded,但它支持onreadystatechange事件。該事件的目的是提供與文檔或元素的加載狀態有關的信息,支持onreadystatechange事件的每個對象都有一個readyState屬性,可能包含下列5個值中的一個:

  • uninitialized(爲初始化):對象存在但尚未初始化。

  • loading(正在加載):對象正在加載數據。

  • loaded(加載完畢):對象加載數據完成。

  • interactive(交互):可以操作對象了,但還沒有完全加載。

  • complete(完成):對象已經加載完畢。

onreadystatechange事件可以用於檢測DOM是否加載完畢,當document.readyState == 'complete'時,表示DOM加載完成。但是如果頁面中有iframe的話,會等到iframe中的所有資源加載完纔會變成complete,此時也造成了主頁面的延遲。但是即使頁面中沒有iframe,該方式也與onload相似,依然會等到所有資源下載完畢後才觸發。

4. doScroll方法

不過,IE還有個特有的方法doScroll, 通過間隔調用:

document.documentElement.doScroll("left");

可以檢測DOM是否加載完成。 當頁面未加載完成時,該方法會報錯,直到doScroll不再報錯時,就代表DOM加載完成了。該方法更接近DOMContentLoaded的實現。

5. Javascript封裝DOMContentLoaded事

function ready(callback){

    // 目前Mozilla、Opera和webkit 525+內核支持DOMContentLoaded事件
    if (document.addEventListener) {
        document.addEventListener('DOMContentLoaded', function() {
            document.removeEventListener('DOMContentLoaded', arguments.callee, false);
            callback();
        }, false);
    // 如果IE
    } else if(document.attachEvent) {
        // 確保當頁面是在iframe中加載時,事件依舊會被安全觸發
        document.attachEvent('onreadystatechange', function() {
            if (document.readyState == 'complete') {
                document.detachEvent('onreadystatechange', arguments.callee);
                callback();
            }
        });
        // 如果是IE且頁面不在iframe中時,輪詢調用doScroll 方法檢測DOM是否加載完畢
        if (document.documentElement.doScroll && typeof window.frameElement === "undefined") {
            !function() {
                try {
                    document.documentElement.doScroll('left');
                } catch(error) {
                    return setTimeout(arguments.callee, 20);
                }
                callback();
            }();
        }
    }
};

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章