首页 > 语言 > JavaScript > 正文

JS DOMReady事件的六种实现方法总结

2024-05-06 15:06:26
字体:
来源:转载
供稿:网友

在实际应用中,我们经常会遇到这样的场景,当页面加载完成后去做一些事情:绑定事件、DOM操作某些结点等。

原来比较常用的是window的onload 事件,而该事件的实际效果是:当页面解析/DOM树建立完成,并完成了诸如图片、脚本、样式表甚至是iframe中所有资源的下载后才触发的。

这对于很多实际的应用而言有点太“迟”了,比较影响用户体验。

为了解决这个问题,ff中便增加了一个DOMContentLoaded方法,与onload相比,该方法触发的时间更早,它是在页面的DOM内容加载完成后即触发,而无需等待其他资源的加载。

Webkit引擎从版本525(Webkit nightly 1/2008:525+)开始也引入了该事件,Opera中也包含该方法。到目前为止主流的IE仍然没有要添加的意思。

虽然IE下没有,但总是有解决办法的,下文对比了一下几大主流框架对于该事件的兼容性版本实现方案,涉及的框架包括:

1. Prototype
2. jQeury
3. moontools
4. dojo
5. yui
6. ext

一、Prototype

实现代码

(function() {var timer;function fireContentLoadedEvent() {if (document.loaded) return;if (timer) window.clearInterval(timer);document.fire("dom:loaded");document.loaded = true;}if (document.addEventListener) {if (Prototype.Browser.WebKit) {timer = window.setInterval(function() {if (/loaded|complete/.test(document.readyState))fireContentLoadedEvent();}, 0);Event.observe(window, "load", fireContentLoadedEvent);} else {document.addEventListener("DOMContentLoaded",fireContentLoadedEvent, false);}} else {document.write("<"+"script id=__onDOMContentLoaded defer src=//:><//script>");$("__onDOMContentLoaded").onreadystatechange = function() {if (this.readyState == "complete") {this.onreadystatechange = null;fireContentLoadedEvent();}};}})();

实现思路如下:

如果是webkit则轮询document的readyState属性,如果该属性的值为loaded或complete则触发DOMContentLoaded事件,为保险起见,将该事件注册到window.onload上。

如果是FF则直接注册DOMContentLoaded事件。

如果是IE则使用document.write往页面中加入一个script元素,并设置defer属性,最后是把该脚本的加载完成视作DOMContentLoaded事件来触发。

该实现方式的问题主要有两点:第一、通过document.write写script并设置defer的方法在页面包含iframe的情况下,会等到 iframe内的内容加载完后才触发,这与onload没有太大的区别;第二、Webkit在525以上的版本引入了DOMContentLoaded方法,因此在这些版本中无需再通过轮询来实现,可以优化。

二、jQuery

function bindReady(){if ( readyBound ) return;readyBound = true;// Mozilla, Opera and webkit nightlies currently support this eventif ( document.addEventListener ) {// Use the handy event callbackdocument.addEventListener( "DOMContentLoaded", function(){document.removeEventListener( "DOMContentLoaded", arguments.callee, false );jQuery.ready();}, false );// If IE event model is used} else if ( document.attachEvent ) {// ensure firing before onload,// maybe late but safe also for iframesdocument.attachEvent("onreadystatechange", function(){if ( document.readyState === "complete" ) {document.detachEvent( "onreadystatechange", arguments.callee );jQuery.ready();}});// If IE and not an iframe// continually check to see if the document is readyif ( document.documentElement.doScroll && typeof window.frameElement === "undefined" ) (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 functionsjQuery.ready();})();}// A fallback to window.onload, that will always workjQuery.event.add( window, "load", jQuery.ready );}            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选