Javascript 如何在没有框架的情况下检查DOM是否就绪?

Javascript 如何在没有框架的情况下检查DOM是否就绪?,javascript,dom,domready,Javascript,Dom,Domready,这个问题就像这里和网络上的无数其他问题一样——如何检查DOM是否加载了Javascript?但问题是: 不使用jQuery等框架 不知道您的脚本是通过静态放置的标记加载的,还是在DOM加载之后很久通过其他Javascript加载的 是否可以通过跨浏览器兼容性或多或少可靠地完成此操作 添加:让我澄清一下:我正在编写一个独立的.JS文件,可以包含在任意网页中。我想在加载DOM后执行代码。但是我不知道我的脚本将如何被收录。它可以通过放置标签(在这种情况下,传统的onload或DOM就绪解决方案将起

这个问题就像这里和网络上的无数其他问题一样——如何检查DOM是否加载了Javascript?但问题是:

  • 不使用jQuery等框架
  • 不知道您的脚本是通过静态放置的
    标记加载的,还是在DOM加载之后很久通过其他Javascript加载的
是否可以通过跨浏览器兼容性或多或少可靠地完成此操作


添加:让我澄清一下:我正在编写一个独立的.JS文件,可以包含在任意网页中。我想在加载DOM后执行代码。但是我不知道我的脚本将如何被收录。它可以通过放置
标签(在这种情况下,传统的
onload
或DOM就绪解决方案将起作用);或者可以通过AJAX或其他方式加载,在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>

window.onload=(函数(oldOnLoad){
返回函数(){
如果(oldOnLoad){
olOnLoad();//触发附加的旧Onload事件(如果有)。
}
//加载图像/脚本后要运行的代码
}
})(窗口加载);
//加载DOM后要运行的代码
编辑:供维尔克斯评论


这里的许多onload绑定就是一个例子,基于Firefox、Opera和Webkit的浏览器都有一个文档级事件
DOMContentLoaded
,您可以使用
document.addEventListener(“DOMContentLoaded”,fn,false)

IE中的情况更为复杂。jQuery在IE中所做的是通过document.onload事件的备份对特定readystate的文档对象进行监视
onreadystatechange
。document.onload在DOM准备就绪之后触发(仅当所有图像都已完成加载时),因此它仅在早期事件因某种原因无法工作时用作后盾

如果你花一些时间在谷歌上搜索,你会发现代码可以做到这一点。我认为在jQuery和YUI这样的大型框架中,要做到这一点,最需要审查的代码是,即使我没有使用这个框架,我也会在它们的源代码中寻找技术

以下是jQuery 1.6.2源代码的主要部分,用于
document.ready()

属性可用于检查文档是否准备就绪。来自MDN:

价值观 文档的readyState可以是以下之一:

  • 加载–文档仍在加载中
  • 交互式–文档已完成加载,文档已被解析,但图像、样式表和帧等子资源仍在加载
  • 完成–文档和所有子资源已完成加载。该状态指示事件即将触发
代码示例:

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!
    });
}

如果依赖于
document.readyState
是正常的,则使用轮询的快速脏解决方案:

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

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

var execute = function () {
  alert("executing code");  
};

if ( !!(window.addEventListener) )
  window.addEventListener("DOMContentLoaded", execute)
else // MSIE
  window.attachEvent("onload", execute)

DOMContentLoaded
事件在初始HTML文档完全加载和解析后触发,而不必等待样式表、图像和子框架完成加载。好消息是chrome、firefox、IE9、opera和safari都同样支持它

document.addEventListener("DOMContentLoaded", function(event) 
{
    console.log("DOM fully loaded and parsed");
}
注意:Internet Explorer 8支持readystatechange事件,该事件 可用于检测DOM何时准备就绪


+1.您可能希望添加一个解释,说明这是如何工作的,以供稍后搜索并找到可能没有太多经验的人使用。我认为您违反了“不知道您的脚本是否在DOM加载后很久通过静态放置的标记或其他Javascript加载”。很抱歉,我没有说过我在谈论一个独立的脚本。我澄清了这一点。window.onload在加载所有图像/脚本后运行。在我的情况下,我甚至不太在乎,但即使如此,仍然有很多DOM就绪脚本可用,因此不必担心。主要的问题是,我不知道onload事件是否很久以前就已经触发了,因此将另一个处理程序附加到它将没有任何效果。可以使用该属性,尽管我不确定浏览器兼容性…恐怕不是很好(请看这个小实用程序:它大约缩小了0.5kb。@DigitalPlane-我收回了它。它有非常好的浏览器支持!添加它作为答案,我会接受它。再一次,如果我在加载DOM后附加我的事件处理程序,这将不起作用。请看我包含的jQuery源代码。这就是为什么它们有以if(document.readyState==“complete”){这样他们就可以处理文档已经准备好的情况。如果你要构建自己的迷你框架来实现这一点,你必须自己构建这类功能。请记住
addEventListener()
是与IE9一起添加的,IE9当然不适用于Windows XP。这与DOMReady事件模拟的其他解决方案一起使用。首先,这不是跨浏览器有效的解决方案。其次,这也会等待图像加载。这类似于window.onload。您不应该侦听名为
load
而不是
onl的事件吗oad
?[Esterica warning]*我认为使用document.readyState==“complete”比使用document.readyState==“complete”更合适*取决于你的代码将要做什么,等待所有图像加载可能更合适*浏览器制造商如此毫不妥协地不称职不是令人沮丧吗
document.addEventListener("DOMContentLoaded", function(event) 
{
    console.log("DOM fully loaded and parsed");
}