DOM就绪,还是文档载入?

Posted by admin | JavaScript, 原创 | 星期日 11 11月 2007 4:55 下午

继基于Mozilla的浏览器之后,Opera9也支持了DOMContentLoaded事件。DOMContentLoaded事件与window对象的load事件是相对的。也就是说,对于开发跨浏览器的Web应用而言,初始化页面的前提大都是DOM文档就绪,而非整个页面载入完成。因为后者涉及到载入页面中包含的图像及其他二进制内容完成后才能触发页面载入事件(即onload),所以这就要求我们(应该是W3C或者浏览器厂商)必须拿出一个方案,来检测DOM载入完成,而不是等待页面载入完成。

目前浏览器在DOM载入事件(而非onload事件)这个问题上已经划分成了IE、基于Mozilla的浏览器和Opera、Safari三大阵营,它们各自都有自己的解决方案(没有标准化的又一恶果!!),即为编写跨浏览器的脚本,我们必须拿出三套应对这三大阵营各自专有方法的方案来。幸运的是,外国同行已经先我们一步搞出了一些名堂,比如Dean Edwards整合了Matthias Miller、John Resig之后的方案–有意思的是,这个方案的示例页面中使用了美国国家宇航局(NASA)网站上的巨幅太空照片来说明问题:

// Dean Edwards/Matthias Miller/John Resig
function init() {
    // 如果本函数已经被调用过了则退出
    if (arguments.callee.done) return;
    // 为本函数添加标记以便不会被调用两次
    arguments.callee.done = true;
    // 终止计时
    if (_timer) clearInterval(_timer);
    // 其他代码
};
/* 针对基于Mozilla的浏览器及Opera9 */
if (document.addEventListener) {
    document.addEventListener(”DOMContentLoaded”, init, false);
}
/* 针对Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
document.write(”
    src=javascript:void(0)><\/script>”);
var script = document.getElementById(”__ie_onload”);
script.onreadystatechange = function() {
    if (this.readyState == “complete”) {
        init(); // 调用onload事件处理程序
    }
};
/*@end @*/
/* 针对Safari */
if (/WebKit/i.test(navigator.userAgent)) { // 嗅探
    var _timer = setInterval(function() {
    if (/loaded|complete/.test(document.readyState)) {
        init(); // 调用onload事件处理程序
    }
    }, 10);
}
/* 针对其他浏览器 */
window.onload = init;

以上代码应该包含在一个外部js文件中,通过在文档头部中使用<script>标签引入页面。而在我翻译的《Advanced DOM Scripting》一书中,也使用了这个方案定义了addLoadEvent()方法(只是稍有改进)。

参考链接如下(其实是前后相继的三篇不断补充的文章):
http://dean.edwards.name/weblog/2005/02/order-of-events/
http://dean.edwards.name/weblog/2005/09/busted/
http://dean.edwards.name/weblog/2006/06/again/
也可以看看这个:
http://tanny.ica.com/ica/tko/tkoblog.nsf/dx/domcontentloaded-event-for-browsers

使用了DOM载入事件的示例页面如下
http://dean.edwards.name/my/busted3.html

其中,显示在红色背景上的”Page loaded!”字样,说明DOM已经载入完成,脚本已经可以开始对DOM大显身手了!而下面那幅图像(取决于网络连接速度)则会犹抱琵琶半遮面,一点点地显露出它的庐山真面目。只有图像显示(载入)完成,才会触发window.onload事件。所以,Dean 用NASA的巨幅照片的良苦用心也就不言自明了。

还有《Advanced DOM Scripting》的作者Jeff提供的一个类似的示例页面如下(可要有点耐心哟):
http://advanceddomscripting.com/source/chapter4/load/load.html

没有评论 »

还没有评论。

对这篇文章的评论的 RSS 聚合。 TrackBack URI

发表您的评论

验证码  If you cannot see the CheckCode image,please refresh the page again!