如何检测是否触发了DOMContentLoaded

时间:2012-02-26 22:33:24

标签: javascript events readystate

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

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

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

什么是正确的选择?

编辑:

似乎我不够清楚。我有兴趣知道加载事件是否已经发生!!!我已经知道如何解决这个问题!我想知道如何用DOMContentLoaded解决!!!

6 个答案:

答案 0 :(得分:42)

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

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

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

如果您想知道页面何时被加载和解析,但尚未加载所有子资源(更类似于DOMContentLoaded),您可以添加“交互”值:

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

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

This MDN documentation也是一个非常好的读物,可以更好地了解DOM状态。

答案 1 :(得分:14)

触发此事件时会更改document.readyState。 因此,您可以检查readyState值,这样就可以判断事件是否被触发。 这是在文档准备就绪时运行start()的代码:

if (/comp|inter|loaded/.test(document.readyState)){
    // In case DOMContentLoaded was already fired, the document readyState will be one of "complete" or "interactive" or (nonstandard) "loaded".
    // The regexp above looks for all three states. A more readable regexp would be /complete|interactive|loaded/
    start();
}else{
    // In case DOMContentLoaded was not yet fired, use it to run the "start" function when document is read for it.
    document.addEventListener('DOMContentLoaded', start, false);
}

答案 2 :(得分:2)

试试这个或查看此link

<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将不会触发 - 直到加载样式表

答案 3 :(得分:1)

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

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

然后检查:

if(loaded) ...

答案 4 :(得分:0)

如何在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
  • window的{​​{1}}事件被触发
  • DOMContentLoaded更改为document.readyState
  • complete的{​​{1}}事件被触发window

您可以在页面加载期间in this fiddle查看事件的完整顺序。

答案 5 :(得分:-4)

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