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

Javascript
javascript比较文档位置
关于document.cookie的使用javascript
js让一行页脚保持在底部
多浏览器兼容的右下角广告代码(已测)
javascript onkeydown实现键盘快捷键控制页面
javascript的键盘控制事件说明
不懂JavaScript应该怎样学
用javascript实现截取字符串包含中文处理的函数
摘自启点的main.js
js tab效果代码增强版
慢慢展开再慢慢收起的javascript广告效果
javascript String 对象
JS查看对象功能代码
javascript点击才出现验证码
js实现双击单元格变成文本输入框效果代码
js通用滑动门类
js动画效果打开层 关闭层
js插入字符到textarea的效果代码
javascript 获取网页标题
js调用flash的效果代码

Javascript 中的 JS教程:addDOMLoadEvent事件


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-09-28   浏览: 372 ::
收藏到网摘: 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();
       
    }
    });

扩展阅读: