如何检查DOM是否准备好没有框架?

这个问题是如此像在这里和在networking上的其他人 – 如何检查DOM是否加载了Javascript? 但是这里有一个问题:

  • 不使用像jQuery等框架;
  • 不知道你的脚本是否已经通过一个静态放置的<script>标记加载,或者在DOM已经加载后很久以后通过其他一些Javascript加载。

这可以或多或less可靠地完成,并具有跨浏览器兼容性?

补充:让我澄清:我正在写一个独立的.JS文件,可以包含在任意的网页。 我想要在加载DOM 之后执行代码。 但我不知道我的脚本将如何被包括在内。 可以通过放置一个<script>标签(在这种情况下,传统的onload或DOM准备就绪解决scheme将起作用)。 或者可以通过AJAX或其他方式加载,在DOM已经加载之后很久(所以前面提到的解决scheme永远不会被触发)。

document.readyState属性可用于检查文档是否准备就绪:

 if(document.readyState === "complete") { //Already loaded! } else { //Add onload or DOMContentLoaded event listeners here: for example, window.addEventListener("onload", function () {/* your code here */}, false); //or //document.addEventListener("DOMContentLoaded", function () {/* code */}, false); } 

基于Firefox,Opera和基于Webkit的浏览器具有文档级事件DOMContentLoaded ,您可以使用document.addEventListener("DOMContentLoaded", fn, false)来侦听。

IE中比较复杂。 jQuery在IE中做什么是通过document.onload事件的备份来监视文档对象上的onreadystatechange对于特定的readystate。 document.onload会在DOM准备好后才会触发(只有当所有的图像加载完成后),所以只有当早期的事件因为某些原因而不起作用的时候,它才被用作backstop。

如果你花一些时间Googlesearch,你会发现代码来做到这一点。 我认为最经审查的代码是在像jQuery和YUI这样的大型框架中,即使我没有使用这个框架,我也会在他们的源代码中寻找技术。

这里是document.ready()的jQuery 1.6.2源代码的主要部分:

 bindReady: function() { if ( readyList ) { return; } readyList = jQuery._Deferred(); // Catch cases where $(document).ready() is called after the // browser event has already occurred. if ( document.readyState === "complete" ) { // Handle it asynchronously to allow scripts the opportunity to delay ready return setTimeout( jQuery.ready, 1 ); } // Mozilla, Opera and webkit nightlies currently support this event if ( document.addEventListener ) { // Use the handy event callback document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); // A fallback to window.onload, that will always work window.addEventListener( "load", jQuery.ready, false ); // If IE event model is used } else if ( document.attachEvent ) { // ensure firing before onload, // maybe late but safe also for iframes document.attachEvent( "onreadystatechange", DOMContentLoaded ); // A fallback to window.onload, that will always work window.attachEvent( "onload", jQuery.ready ); // If IE and not a frame // continually check to see if the document is ready var toplevel = false; try { toplevel = window.frameElement == null; } catch(e) {} if ( document.documentElement.doScroll && toplevel ) { doScrollCheck(); } } }, 

这适用于所有浏览器,并且简洁明了:

 var execute = function () { alert("executing code"); }; if ( !!(window.addEventListener) ) window.addEventListener("DOMContentLoaded", execute) else // MSIE window.attachEvent("onload", execute) 

如果依靠document.readyState是可以的,那么使用轮询的快速解决scheme:

 (function() { var state = document.readyState; if(state === 'interactive' || state === 'complete') { // do stuff } else setTimeout(arguments.callee, 100); })(); 

DOMContentLoaded事件是在初始HTML文档被完全加载和parsing的时候触发的,没有等待样式表,图像和子帧完成加载。好东西是铬,firefox,IE9,opera和safari同样支持它

 document.addEventListener("DOMContentLoaded", function(event) { console.log("DOM fully loaded and parsed"); } 

注:Internet Explorer 8支持readystatechange事件,可用于检测DOM何时准备就绪。

这是通过在页面底部运行脚本的一种方法。 另外通过使用window.onload,你可以等待所有的图像/脚本加载。 或者你可以简单地把代码放在底部而不是等待加载图像。

 <html> <head> </head> <body> </body> <script language="text/javascript"> window.onload = (function (oldOnLoad) { return function () { if (oldOnLoad) { olOnLoad(); //fire old Onload event that was attached if any. } // your code to run after images/scripts are loaded } })(window.onload); // your code to run after DOM is loaded </script> </html> 

编辑:Vilx的评论

许多onload绑定在这里是一个例子http://jsfiddle.net/uTF2N/3/