如何检查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/