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

时间:2011-11-11 22:10:03

标签: javascript dom domready

问题就像在这里和网络上的其他人一样 - 如何检查DOM是否已加载Javascript?但是这里有一个问题:

  • 不使用jQuery等框架;
  • 不知道您的脚本是否已经通过静态放置的<script>标记加载,或者在DOM加载后很久之后通过其他一些Javascript加载。

这可以或多或少可靠地完成并且具有跨浏览器兼容性吗?

已添加:让我澄清一下:我正在编写一个独立的.JS文件,可以包含在任意网页中。我想执行已加载DOM的代码 AFTER 。但我不知道 HOW 我的剧本将被包括在内。可以通过放置<script>标记(在这种情况下,传统的onload或DOM-readyiness解决方案将起作用);或者它可以通过AJAX或其他方式加载,很久以后DOM已经加载(所以前面提到的解决方案永远不会触发)。

6 个答案:

答案 0 :(得分:65)

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

答案 1 :(得分:10)

Firefox,Opera和基于Webkit的浏览器都有一个文档级事件DOMContentLoaded,您可以使用document.addEventListener("DOMContentLoaded", fn, false)来监听。

在IE中更复杂。 jQuery在IE中做的是在文档对象上查看具有document.onload事件备份的特定readystate的onreadystatechange。 document.onload会在DOM准备就绪之后触发(仅当所有图像都已完成加载时)才会触发,因此只有在早期事件由于某种原因不起作用的情况下才会用作止回器。

如果您花一些时间使用Google搜索,您会找到执行此操作的代码。我认为执行此操作最多的代码是在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();
        }
    }
},

答案 2 :(得分:8)

如果依赖于document.readyState是可以的,那么使用民意调查的快速解决方案:

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

答案 3 :(得分:8)

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

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

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

答案 4 :(得分:4)

初始HTML文档完全加载和解析后,DOMContentLoaded事件被触发,无需等待样式表,图像和子帧完成加载。好东西是chrome,firefox,IE9,opera和safari支持它同样

document.addEventListener("DOMContentLoaded", function(event) 
{
    console.log("DOM fully loaded and parsed");
}
  

注意:Internet Explorer 8支持readystatechange事件   可以用来检测DOM何时就绪。

答案 5 :(得分:2)

这是通过在页面底部运行脚本的一种方法。此外,通过使用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/