DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> 關於JavaScript >> JS教程:addDOMLoadEvent事件
JS教程:addDOMLoadEvent事件
編輯:關於JavaScript     

網頁制作poluoluo文章簡介:由於 window.onload 事件需要在頁面所有內容(包括圖片等)加載完後,才執行,但往往我們更希望在 DOM 一加載完就執行腳本。其實在現在大部分主流浏覽器上(Firefox 3+,Opera 9+,Safari 3+,Chrome 2+)都提供了這一事件方法:addDOMLoadEvent。

由於 window.onload 事件需要在頁面所有內容(包括圖片等)加載完後,才執行,但往往我們更希望在 DOM 一加載完就執行腳本。其實在現在大部分主流浏覽器上(Firefox 3+,Opera 9+,Safari 3+,Chrome 2+)都提供了這一事件方法:addDOMLoadEvent

document.addEventListener("DOMContentLoaded", init, false);

那對於 IE 我們如何模擬 addDOMLoadEvent 事件呢?

Matthias Miller 最早提供了如下的解決方案:

// for Internet Explorer (using conditional comments)
/*@cc_on @*/
/*@if (@_win32)
document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
var script = document.getElementById("__ie_onload");
script.onreadystatechange = function() {
    if (this.readyState == "complete") {
        init(); // call the onload handler
    }
};
/*@end @*/

而 Diego Perini 在其後提供了一種利用 doScroll() 方法來模擬 addDOMLoadEvent 事件的方案,且現在主流的 JavaScript 框架(JQuery、YUI等)基本都采用的這一解決方案。

原理基本如下:

當 ondocumentready 事件觸發,文檔( document )已經完全解析和建立。如果組件需要操作最初的文檔結構,初始化代碼需被安置在這之後。ondocumentready 事件告知組件,整個頁面已被加載,且在 初始文檔的 onload 事件觸發之前立即觸發。

一些方法,例如 doScroll,要求最初的文檔被完全加載。如果這些方法是初始化函數的一部分,當ondocumentready 事件觸發,他們將被執行。

/*
 *
 * IEContentLoaded.js
 *
 * Author: Diego Perini (diego.perini at gmail.com) NWBOX S.r.l.
 * Summary: DOMContentLoaded emulation for IE browsers
 * Updated: 05/10/2007
 * License: GPL/CC
 * Version: TBD
 *
 */

// @w    window reference
// @fn    function reference
function IEContentLoaded (w, fn) {
    var d = w.document, done = false,
    // only fire once
    init = function () {
        if (!done) {
            done = true;
            fn();
        }
    };
    // polling for no errors
    (function () {
        try {
            // throws errors until after ondocumentready
            d.documentElement.doScroll('left');
        } catch (e) {
            setTimeout(arguments.callee, 50);
            return;
        }
        // no errors, fire
        init();
    })();
    // trying to always fire before onload
    d.onreadystatechange = function() {
        if (d.readyState == 'complete') {
            d.onreadystatechange = null;
            init();
        }
    };
}

JQuery 1.3.2 中源碼實現如下:

// If IE and not an iframe
// continually check to see if the document is ready
if ( document.documentElement.doScroll && window == window.top ) (function(){
    if ( jQuery.isReady ) return;

    try {
        // If IE is used, use the trick by Diego Perini
        // http://javascript.nwbox.com/IEContentLoaded/
        document.documentElement.doScroll("left");
    } catch( error ) {
        setTimeout( arguments.callee, 0 );
        return;
    }

    // and execute any waiting functions
    jQuery.ready();
})();

YUI 2.7.0 中源碼實現如下:

if (EU.isIE) {

    // Process onAvailable/onContentReady items when the
    // DOM is ready.
    YAHOO.util.Event.onDOMReady(
            YAHOO.util.Event._tryPreloadAttach,
            YAHOO.util.Event, true);

    var n = document.createElement('p');  

    EU._dri = setInterval(function() {
        try {
            // throws an error if doc is not ready
            n.doScroll('left');
            clearInterval(EU._dri);
            EU._dri = null;
            EU._ready();
            n = null;
        } catch (ex) {
        }
    }, EU.POLL_INTERVAL);

}

另外對於版本小於 Safari 3+ 的 Safari 浏覽器,John Resig 也提供了一個解決方案:

if (/WebKit/i.test(navigator.userAgent)) { // sniff
    var _timer = setInterval(function() {
        if (/loaded|complete/.test(document.readyState)) {
            clearInterval(_timer);
            init(); // call the onload handler
        }
    }, 10);
}

怿飛提示:

  1. 如果腳本是動態注入到頁面上,則原生的 DOMContentReady 事件是不會被觸發(即:IE 除外)。
  2. IE 下對於在 iframe 裡的使用 addDOMLoadEvent 事件,需做處理和慎用(這一點 YUI 做得不如 JQuery 細致)。
    // form JQuery 1.3.2
    // ensure firing before onload, maybe late but safe also for iframes
    document.attachEvent("onreadystatechange", function(){
        if ( document.readyState === "complete" ) {
            document.detachEvent( "onreadystatechange", arguments.callee );
            jQuery.ready();
        }
    });

擴展閱讀:

  • 《addDOMLoadEvent》
  • 《window.onload (again)》
  • 《IEContentLoaded》

XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved