67

我正在尝试帮助开发一个库,为此我正在尝试使用页面加载。
在这个过程中,我想让库完全兼容 defer 和 async 的使用。

我想要的很简单:
我怎么知道 DOMContentLoaded 在文件执行时被触发了?

为什么这么难?
在 IE 中,document.readyState 在 DOMContentLoaded 之前显示交互。
不会以任何方式使用浏览器检测,这违反了我和其他参与者的政策。

什么是正确的选择?

编辑:

好像我说的不够清楚。我不想知道加载事件是否已经发生!!!我已经知道如何解决这个问题了!我想知道如何用 DOMContentLoaded 解决!!!

4

6 回答 6

71

查看页面中的所有资源是否已加载:

if (document.readyState === "complete" || document.readyState === "loaded") {
     // document is already ready to go
}

这在 IE 和 webkit 中已经支持很长时间了。它在 3.6 中被添加到 Firefox。这是规范"loaded"适用于较旧的 Safari 浏览器。

如果你想知道页面何时被加载和解析,但所有子资源还没有被加载(这更类似于DOMContentLoaded),你可以添加“interactive”值:

if (document.readyState === "complete" 
     || document.readyState === "loaded" 
     || document.readyState === "interactive") {
     // document has at least been parsed
}

除此之外,如果您真的只想知道 DOMContentLoaded 何时触发,那么您必须为它安装一个事件处理程序(在它触发之前)并在它触发时设置一个标志。

这个 MDN 文档对于了解更多关于 DOM 状态的知识也是一本非常好的读物。

于 2012-02-26T22:45:14.757 回答
21

您可以检查文档的readyState值,这样可以判断事件是否被触发。start()以下是在文档完成解析时运行名为的函数的代码:

if (/complete|interactive|loaded/.test(document.readyState)) {
    // In case the document has finished parsing, document's readyState will
    // be one of "complete", "interactive" or (non-standard) "loaded".
    start();
} else {
    // The document is not ready yet, so wait for the DOMContentLoaded event
    document.addEventListener('DOMContentLoaded', start, false);
}

请注意,上面的代码检测文档何时完成解析。请注意,这与检测是否DOMContentLoaded被触发(在 之后立即发生 interactive)不同,但它具有相同的实际目的,即它告诉您文档已完成加载并已被解析,但图像、样式表等子资源并且框架仍在加载(source)。

于 2016-03-14T20:03:34.660 回答
8

如何在 DOMContentLoaded(或 ASAP)上正确运行某些东西

如果您需要等待 HTML 文档完全加载并解析运行某些东西,那么您需要等待DOMContentLoaded,这是毫无疑问的。但是,如果您无法控制脚本何时执行,则可能DOMContentLoaded在您有机会侦听事件时已经触发。

考虑到这一点,您的代码需要检查是否DOMContentLoaded已经触发,如果是,则立即继续执行需要等待的任何内容DOMContentLoaded

function runWhenPageIsFullyParsed() {
    // your logic goes here
}

if (document.readyState === "complete") {
    // already fired, so run logic right away
    runWhenPageIsFullyParsed();
} else {
    // not fired yet, so let's listen for the event
    window.addEventListener("DOMContentLoaded", runWhenPageIsFullyParsed);
}

页面加载期间事件的正确顺序是:

  • document.readyState更改为interactive
  • windowDOMContentLoaded事件被触发
  • document.readyState更改为complete
  • windowload事件被触发load

您可以在此小提琴中检查页面加载期间事件的完整顺序。

于 2019-12-06T21:12:41.947 回答
1

试试这个或看看这个链接

<script>
    function addListener(obj, eventName, listener) { //function to add event
        if (obj.addEventListener) {
            obj.addEventListener(eventName, listener, false);
        } else {
            obj.attachEvent("on" + eventName, listener);
        }
    }

    addListener(document, "DOMContentLoaded", finishedDCL); //add event DOMContentLoaded

    function finishedDCL() {
        alert("Now DOMContentLoaded is complete!");
    }
</script>

笔记

如果你有一个<script>之后<link rel="stylesheet" ...>

在加载样式表之前,页面不会完成解析 - 并且DOMContentLoaded不会触发

于 2012-02-27T06:49:02.783 回答
0

如果您想“确切地”知道 DOMContentLoaded 是否被触发,您可以使用这样的布尔标志:

var loaded=false;
document.addEventListener('DOMContentLoaded',function(){
loaded=true;
...
}

然后检查:

if(loaded) ...
于 2014-03-20T19:52:36.660 回答
-8

事情是这样的,如果其他一些库(比如 jQuery)已经使用了 DOMContentLoaded,你就不能再使用它了。这可能是个坏消息,因为您最终无法使用它。你会说,为什么不直接使用$(document).ready(),因为,不!,不是所有东西都需要使用 jQuery,特别是如果它是一个不同的库。

于 2016-08-19T21:22:59.557 回答