当前位置: 首页 > 图文教程 > 网络编程 > Javascript > JS教程:addDOMLoadEvent事件

Javascript
颜色变换 像字符逐字输入的欢迎词
CSS 伪类实现的鼠标滑动图片链接
百度用到的Js日历 大家可以看看
CSS 渐变背景的6个演示代码
Jquery 弹出层插件实现代码
Javascript 模式实例 观察者模式
[原创]javascript 指定区域内图片等比例缩放实现代码 脚本之家整合版
javascript window对象属性整理
JavaScript弹簧振子超简洁版 完全符合能量守恒,胡克定理
WEB页子窗口(showModalDialog和showModelessDialog)使用说明
用JavaScript实现 铁甲无敌奖门人 “开口中”猜数游戏
理解 JavaScript 预解析
理解JavaScript变量作用域更轻松
JavaScript的变量作用域深入理解
javascript写的一个链表实现代码
Js 打字效果 逐一出现的文字
javascript 走马灯效果的链接提示
CSS 动态链接提示
JavaScript 事件的一些重要说明
JavaScript 三种不同位置代码的写法

Javascript 中的 JS教程:addDOMLoadEvent事件


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 117 ::
收藏到网摘: n/a

由于 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();
       
    }
    });

扩展阅读: