Javascript 如何在没有框架的情况下检查 DOM 是否准备就绪?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8100576/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check if DOM is ready without a framework?
提问by Vilx-
The question is so like a zillion others here and on the web - How to check if DOM has loaded in Javascript? But here's the catch:
问题就像这里和网络上的无数其他人一样 - 如何检查 DOM 是否已在 Javascript 中加载?但这里有一个问题:
- Without using a framework like jQuery etc;
- Without knowing if your script has been loaded via a statically placed
<script>
tag or via some other Javascript much later after the DOM has already loaded.
- 不使用 jQuery 等框架;
- 不知道您的脚本是通过静态放置的
<script>
标签还是在 DOM 加载之后很久才通过其他一些 Javascript 加载的。
Can this be done more or less reliably and with cross-browser compatibility?
这是否可以或多或少地可靠地完成并具有跨浏览器兼容性?
Added:Let me clarify: I'm writing a standalone .JS file which can be included in arbitrary webpages. I want to execute code AFTERthe DOM has been loaded. But I don't know HOWmy script will be included. It could be by placing a <script>
tag (in which case the traditional onload
or DOM-readiness solutions will work); or it could be loaded via AJAX or some other means, much later after the DOM is already loaded (so the previously mentioned solutions will never fire).
补充:让我澄清一下:我正在编写一个独立的 .JS 文件,它可以包含在任意网页中。我想在加载 DOM后执行代码。但我不知道如何包含我的脚本。可以通过放置<script>
标签(在这种情况下,传统onload
或 DOM 就绪解决方案将起作用);或者它可以通过 AJAX 或其他方式加载,在 DOM 已经加载之后很久(所以前面提到的解决方案永远不会触发)。
回答by Digital Plane
The document.readyState
property can be used to check if the document is ready. From MDN:
该document.readyState
属性可用于检查文档是否准备就绪。来自 MDN:
Values
The readyState of a document can be one of following:
- loading– The document is still loading.
- interactive– The document has finished loading and the document has been parsed but sub-resources such as images, stylesheets and frames are still loading.
- complete– The document and all sub-resources have finished loading. The state indicates that the loadevent is about to fire.
价值观
文档的 readyState 可以是以下之一:
- 加载- 文档仍在加载。
- 交互式- 文档已完成加载并且文档已被解析,但诸如图像、样式表和框架之类的子资源仍在加载。
- complete- 文档和所有子资源已完成加载。状态指示加载事件即将触发。
Code example:
代码示例:
if(document.readyState === "complete") {
// Fully loaded!
}
else if(document.readyState === "interactive") {
// DOM ready! Images, frames, and other subresources are still downloading.
}
else {
// Loading still in progress.
// To wait for it to complete, add "DOMContentLoaded" or "load" listeners.
window.addEventListener("DOMContentLoaded", () => {
// DOM ready! Images, frames, and other subresources are still downloading.
});
window.addEventListener("load", () => {
// Fully loaded!
});
}
回答by jfriend00
Firefox, Opera and Webkit-based browsers have a document-level event DOMContentLoaded
that you can listen for with document.addEventListener("DOMContentLoaded", fn, false)
.
Firefox、Opera 和基于 Webkit 的浏览器有一个文档级事件DOMContentLoaded
,您可以使用document.addEventListener("DOMContentLoaded", fn, false)
.
It is more complicated in IE. What jQuery does in IE is watch onreadystatechange
on the document object for a particular readystate with a backup of the document.onload event. document.onload fires later than the DOM is ready (only when all images have finished loading) so it's only used as a backstop in case the earlier events don't work for some reason.
在 IE 中更复杂。jQuery 在 IE 中所做的是onreadystatechange
通过 document.onload 事件的备份监视文档对象的特定就绪状态。document.onload 在 DOM 准备好之后触发(仅当所有图像都完成加载时),因此它仅用作支持以防早期事件由于某种原因不起作用。
If you spend some time Googling, you will find code to do this. I figure the most vetted code to do this is in the large frameworks like jQuery and YUI so, even if I'm not using that framework, I look in their source code for techniques.
如果您花一些时间谷歌搜索,您会找到执行此操作的代码。我认为要做到这一点的最经过的代码是在像 jQuery 和 YUI 这样的大型框架中,所以,即使我没有使用那个框架,我也会查看他们的源代码以获取技术。
Here's the main part of jQuery 1.6.2 source for document.ready()
:
这是 jQuery 1.6.2 源代码的主要部分document.ready()
:
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();
}
}
},
回答by Christoph
If relying on document.readyState
is ok, quick-and-dirty solution with polling:
如果依赖没问题document.readyState
,使用轮询的快速解决方案:
(function() {
var state = document.readyState;
if(state === 'interactive' || state === 'complete') {
// do stuff
}
else setTimeout(arguments.callee, 100);
})();
回答by John Foley
This works for all browsers and is short and concise:
这适用于所有浏览器并且简洁明了:
var execute = function () {
alert("executing code");
};
if ( !!(window.addEventListener) )
window.addEventListener("DOMContentLoaded", execute)
else // MSIE
window.attachEvent("onload", execute)
回答by Malik Khalil
The DOMContentLoaded
event is fired when the initial HTML document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.Good thing is chrome, firefox, IE9, opera and safari supports it equally
DOMContentLoaded
当初始 HTML 文档完全加载和解析完毕时触发该事件,无需等待样式表、图像和子框架完成加载。好在 chrome、firefox、IE9、opera 和 safari 都支持它
document.addEventListener("DOMContentLoaded", function(event)
{
console.log("DOM fully loaded and parsed");
}
NOTE : Internet Explorer 8 supports the readystatechange event, which can be used to detect when the DOM is ready.
注意:Internet Explorer 8 支持 readystatechange 事件,可用于检测 DOM 何时准备就绪。
回答by John Hartsock
Here is one way by running script at the bottom of the page. In addition by using the window.onload you can wait for all images/scripts to be loaded. Or you could simply place code at the bottom not waiting for images to be loaded.
这是在页面底部运行脚本的一种方法。此外,通过使用 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>
Edited: for Vilx's Comment
编辑:对于维尔克斯的评论
Many onload bindings here is an example http://jsfiddle.net/uTF2N/3/
这里的许多加载绑定是一个例子http://jsfiddle.net/uTF2N/3/