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

Javascript
提高网站信任度的技巧
javascript脚本编程解决考试分数统计问题
图片上传之前检查大小、尺寸、格式并预览的js代码
JavaScript打开客户端exe文件的代码
JavaScript confirm选择判断
javascript title闪动效果
javascript把15位身份证转成18的函数
新人报道,发个小技巧(js数组重复判断)
Javascript this关键字使用分析
javascript TextArea动态显示剩余字符
JavaScript Undefined,Null类型和NaN值区别
javascript Select标记中options操作方法集合
javascript trim 去空格函数实现代码
javascript网页关闭时提醒效果脚本
checkbox 多选框 联动实现代码
收集的比较全的automation服务器不能创建对象 异常原因和解决方法
Javascript客户端将指定区域导出到Word、Excel的代码
IE浏览器兼容Firefox的JS脚本的代码
在html页面中包含共享页面的方法
javascript replace()用法详解附实例代码

Javascript 中的 JS教程:addDOMLoadEvent事件


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

扩展阅读: