javascript domready?

kri*_*sen 51 javascript javascript-events

我知道我可以使用不同的框架(如prototype或jquery)将函数附加到window.onload,但这不是我正在寻找的.

我需要像.readyState这样的东西,这样我就可以这样做:

if(document.isReady){
  var id = document.getElem ...
}
Run Code Online (Sandbox Code Playgroud)

除了使用框架的功能之外,还有其他方法吗?

Rya*_*ale 43

编辑:随着2018年到来,我认为听这个DOMContentLoaded活动是安全的.

function fireOnReady() { /* ... */ }
if (document.readyState === 'complete') {
    fireOnReady();
} else {
    document.addEventListener("DOMContentLoaded", fireOnReady);
}
Run Code Online (Sandbox Code Playgroud)

请注意,活动只会在您的网页加载时触发一次!如果你必须支持真正的旧浏览器,那么看看我在下面放在一起的超轻量级脚本.



仅供参考:



jQuery有一个名为isReady的未记录属性,它在内部用于确定是否已触发DOM ready事件:

if($.isReady) {
    // DOM is ready
} else {
    // DOM is not yet ready
}
Run Code Online (Sandbox Code Playgroud)

我从1.5.2开始回到1.3.2并且财产就在那里.虽然没有文档,但我会说你可以在将来的jQuery版本中依赖这个属性. 编辑:一年后 - v1.7.2,他们仍然使用$.isReady- 仍然没有记录,所以请自担风险使用.升级时要小心.

编辑: v1.9,他们仍然使用$.isReady- 仍然没有记录

编辑: v2.0,所有它的"主要"更改,仍然使用$.isReady- 仍然没有记录

编辑: v3.x仍然使用$.isReady- 仍然没有记录

编辑:有几个人指出,上面并没有真正回答这个问题.所以我刚刚创建了一个迷你DOM准备片段,其灵感来自Dustin Diaz 甚至更小的DOM准备片段.Dustin创建了一个简洁的方法来检查文件readyState,其内容与此类似:

if( !/in/.test(document.readyState) ) {
    // document is ready
} else {
    // document is NOT ready
}
Run Code Online (Sandbox Code Playgroud)

这样做的原因是因为浏览器有3种加载状态:"加载","交互"和"完整" (旧的WebKit也使用"加载",但你不必再担心了).你会注意到"loading"和"interactive"都包含文本"in"...所以如果在里面找到字符串"in" document.readyState,那么我们知道我们还没准备好.

  • 这不回答问题(OP不想使用框架).但是,它确实为这个标记为"完全重复"的问题提供了一个很好的答案(+1来自我).http://stackoverflow.com/questions/8373910/in-jquery-how-do-i-check-if-the-dom-is-ready (7认同)
  • 不确定为什么投票.我解释说这是没有证件的.在未来版本的jQuery中调试这个问题会非常简单,而且它是那些自我描述的变量之一,永远不会传递"这个更好的名字"测试,因此可能永远不会重命名.无论如何......我希望人们能够解释投票. (3认同)

Bli*_*ixt 32

虽然我通常主张避免使用框架,除非有必要,但我认为在这种情况下使用框架是完全没问题的.这是jQuery:

$(function () {
    // do stuff after DOM has loaded
});
Run Code Online (Sandbox Code Playgroud)

请注意,它与window.onload事件不同,因为onload在加载其他资源(图像等)之后首先执行.我的示例中使用的代码将在DOM完成加载时执行,即,当完整的HTML结构可用时(不一定在图像,CSS等可用时.)

如果需要可检查变量,可以在ready-function中设置一个:

var documentIsReady = false;
$(function () { documentIsReady = true; });
Run Code Online (Sandbox Code Playgroud)

当然,如果你想做的就是检查DOM-ready,你可以找到比jQuery更轻量级的库.但是在不同浏览器行为异常的情况下使用库(这就是这种情况).

使用DOMAssistant库中的一些代码,制作自己的"DOM就绪"功能应该不会太难:

var domLoaded = function (callback) {
    /* Internet Explorer */
    /*@cc_on
    @if (@_win32 || @_win64)
        document.write('<script id="ieScriptLoad" defer src="//:"><\/script>');
        document.getElementById('ieScriptLoad').onreadystatechange = function() {
            if (this.readyState == 'complete') {
                callback();
            }
        };
    @end @*/
    /* Mozilla, Chrome, Opera */
    if (document.addEventListener) {
        document.addEventListener('DOMContentLoaded', callback, false);
    }
    /* Safari, iCab, Konqueror */
    if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) {
        var DOMLoadTimer = setInterval(function () {
            if (/loaded|complete/i.test(document.readyState)) {
                callback();
                clearInterval(DOMLoadTimer);
            }
        }, 10);
    }
    /* Other web browsers */
    window.onload = callback;
};
Run Code Online (Sandbox Code Playgroud)

没有经过测试,但应该可行.我从DOMAssistant中简化了它,因为DOMAssistant允许多个回调并且检查以确保你不能两次添加相同的函数等.

  • 这是我从框架中唯一需要的东西,它需要服务的其他东西,我不需要,所以如果可能的话,我宁愿在这种情况下不使用框架,否则我会选择jquery (4认同)

Dam*_*ith 29

在问题被问到这五年后,DOMContentLoaded已成为普遍支持的事件,您可以使用它.

document.addEventListener('DOMContentLoaded', function() {
    //.. do stuff ..
}, false);
Run Code Online (Sandbox Code Playgroud)


Ran*_*tka 10

从微软查看这个演示.- > http://ie.microsoft.com/testdrive/HTML5/DOMContentLoaded/Default.html以下 是允许您在DOM上运行JS的代码的要点......

(function () {
    function load2(){
        // put whatever you need to load on DOM ready in here
        document.getElementById("but3").addEventListener("click", doMore, false);
    }
    if (window.addEventListener) {
        window.addEventListener('DOMContentLoaded', load2, false);
    } else {
        window.attachEvent('onload', load2);
    }
} ());
Run Code Online (Sandbox Code Playgroud)

以下是演示的一些javascript源代码.. http://ie.microsoft.com/testdrive/Includes/Script/ReturnAndShareControls.js

它运作良好.很棒!! ..在谷歌Chrome和IE 9.


Pat*_*hon 10

document.addEventListener("DOMContentLoaded", function(e){
    console.log("dom ready");//output to web browser console
});
Run Code Online (Sandbox Code Playgroud)

没有JQuery需要这个.无需在DOMContentLoaded上传递第3个参数,因为此事件没有父级来遍历事件.也没有必要对其他人说的都充满乐趣.这将告诉您DOM何时完全加载并准备使用.当我注意到DOM助手lib时,我感到很沮丧.这个lib绝对没用.

完全加载和解析文档时会触发DOMContentLoaded事件,而无需等待样式表,图像和子帧完成加载

addEventListener()是一个很好的功能,用于检查任何事件,包括DOM就绪状态.使用"DOMContentLoaded"时,addEventListener()不需要第3个参数,因为此触发器也没有父项来传递事件.在上面的例子中,您会注意到第二个参数是一个匿名函数.您还可以将函数名称传递给第二个参数.

document.addEventListener([(string)event trigger], [function],[(boolean)traverse DOM tree]);
Run Code Online (Sandbox Code Playgroud)

使用它比JQuery更好的另一个好处是当你更新JQuery时这不会破坏.


Yeh*_*hia 8

我已经更新了DOMAssistant库的代码,它可以和我一起使用

var domReady = (function (){
  var arrDomReadyCallBacks = [] ;
  function excuteDomReadyCallBacks(){
       for (var i=0; i < arrDomReadyCallBacks.length; i++) {
         arrDomReadyCallBacks[i]();
       }
       arrDomReadyCallBacks = [] ;
  }

  return function (callback){
    arrDomReadyCallBacks.push(callback);
     /* Mozilla, Chrome, Opera */
      if (document.addEventListener ) {
          document.addEventListener('DOMContentLoaded', excuteDomReadyCallBacks, false);
      }
    /* Safari, iCab, Konqueror */
    if (/KHTML|WebKit|iCab/i.test(navigator.userAgent)) {
        browserTypeSet = true ;
        var DOMLoadTimer = setInterval(function () {
            if (/loaded|complete/i.test(document.readyState)) {
                //callback();
                excuteDomReadyCallBacks();
                clearInterval(DOMLoadTimer);
            }
        }, 10);
    }
    /* Other web browsers */

    window.onload = excuteDomReadyCallBacks;
}
})()
Run Code Online (Sandbox Code Playgroud)


Jus*_*ner 6

jQuery不使用window.onload.

$(document).ready() 等待直到DOM加载并且可以遍历(其余内容可能会或可能不会被该点加载).

如果您提取jQuery的源代码并对混乱进行排序,您会发现该工作是通过该bindReady()方法完成的,该方法针对不同的浏览器有几种不同的实现方式,并且只有当所有这些实现都失败时才会回退到监听负载窗口的事件.