Javascript - 如何检测文档是否已加载(IE 7 / Firefox 3)

时间:2009-06-11 00:14:39

标签: javascript events onload addeventlistener

我想在文档加载后调用函数,但文档可能已经或可能尚未完成加载。如果它确实加载了,那么我可以调用该函数。如果它没有加载,那么我可以附加一个事件监听器。我无法在onload已经触发后添加一个eventlistener,因为它不会被调用。那么如何检查文档是否已加载?我尝试了下面的代码,但它并不完全有用。有什么想法吗?

var body = document.getElementsByTagName('BODY')[0];
// CONDITION DOES NOT WORK
if (body && body.readyState == 'loaded') {
    DoStuffFunction();
} else {
    // CODE BELOW WORKS
    if (window.addEventListener) {  
        window.addEventListener('load', DoStuffFunction, false);
    } else {
        window.attachEvent('onload', DoStuffFunction);
    }
}

9 个答案:

答案 0 :(得分:242)

没有必要使用galambalazs提到的所有代码。在纯JavaScript中使用跨浏览器的方式只是测试document.readyState

if (document.readyState === "complete") { init(); }

这也是jQuery如何做到的。

根据JavaScript的加载位置,可以在一个时间间隔内完成:

var readyStateCheckInterval = setInterval(function() {
    if (document.readyState === "complete") {
        clearInterval(readyStateCheckInterval);
        init();
    }
}, 10);

事实上,document.readyState可以有三种状态:

  

在文档加载时返回“loading”,在完成解析但仍加载子资源时返回“interactive”,并在加载后“完成”。    - document.readyState at Mozilla Developer Network

因此,如果您只需要准备好DOM,请检查document.readyState === "interactive"。如果您需要准备好整个页面,包括图像,请检查document.readyState === "complete"

答案 1 :(得分:32)

不需要图书馆。 jQuery使用这个脚本一段时间了,顺便说一句。

http://dean.edwards.name/weblog/2006/06/again/

// Dean Edwards/Matthias Miller/John Resig

function init() {
  // quit if this function has already been called
  if (arguments.callee.done) return;

  // flag this function so we don't do the same thing twice
  arguments.callee.done = true;

  // kill the timer
  if (_timer) clearInterval(_timer);

  // do stuff
};

/* for Mozilla/Opera9 */
if (document.addEventListener) {
  document.addEventListener("DOMContentLoaded", init, false);
}

/* for Internet Explorer */
/*@cc_on @*/
/*@if (@_win32)
  document.write("<script id=__ie_onload defer src=javascript:void(0)><\/script>");
  var script = document.getElementById("__ie_onload");
  script.onreadystatechange = function() {
    if (this.readyState == "complete") {
      init(); // call the onload handler
    }
  };
/*@end @*/

/* for Safari */
if (/WebKit/i.test(navigator.userAgent)) { // sniff
  var _timer = setInterval(function() {
    if (/loaded|complete/.test(document.readyState)) {
      init(); // call the onload handler
    }
  }, 10);
}

/* for other browsers */
window.onload = init;

答案 2 :(得分:15)

您可能希望使用类似jQuery的东西,这样可以简化JS编程。

类似的东西:

$(document).ready(function(){
   // Your code here
});

似乎会做你想做的事。

答案 3 :(得分:5)

如果您确实希望此代码在 load 上运行,而不是在domready(即您还需要加载图像),那么很遗憾,ready函数不会为您执行此操作。我通常只做这样的事情:

包含在文档javascript中(即在onload触发之前始终调用):

var pageisloaded=0;
window.addEvent('load',function(){
 pageisloaded=1;
});

然后你的代码:

if (pageisloaded) {
 DoStuffFunction();
} else {
 window.addEvent('load',DoStuffFunction);
}

(或者在您的首选框架中的等价物。)我使用此代码来为将来的页面预先缓存javascript和图像。由于我得到的东西根本不用于此页面,我不希望它优先于快速下载图像。

可能有更好的方法,但我还没有找到它。

答案 4 :(得分:4)

if(document.loaded) {
    DoStuffFunction();
} else {
    if (window.addEventListener) {  
        window.addEventListener('load', DoStuffFunction, false);
    } else {
        window.attachEvent('onload', DoStuffFunction);
    }
}

答案 5 :(得分:3)

上面的JQuery是最容易使用的方式。但是你可以使用纯javascript,但尝试在头部定义这个脚本,以便在开头读取它。你要找的是window.onload事件。

下面是我为运行计数器而创建的一个简单脚本。然后计数器在10次迭代后停止

window.onload=function()
{
    var counter = 0;
    var interval1 = setInterval(function()
    { 
        document.getElementById("div1").textContent=counter;
        counter++; 
        if(counter==10)
        {
            clearInterval(interval1);
        }
    },1000);

}

答案 6 :(得分:3)

Mozila Firefox说onreadystatechangeDOMContentLoaded的替代品。

// alternative to DOMContentLoaded
document.onreadystatechange = function () {
    if (document.readyState == "complete") {
        initApplication();
    }
}

DOMContentLoaded,Mozila的医生说:

  

文档发布时会触发DOMContentLoaded事件   完全加载和解析,无需等待样式表,图像,   和子帧完成加载(加载事件可用于检测   一个完整的页面。)

我认为load事件应该用于完整的文档+资源加载。

答案 7 :(得分:2)

试试这个:

var body = document.getElementsByTagName('BODY')[0];
// CONDITION DOES NOT WORK
if ((body && body.readyState == 'loaded') || (body &&  body.readyState == 'complete') ) {
    DoStuffFunction();
} else {
    // CODE BELOW WORKS
    if (window.addEventListener) {
        window.addEventListener('load', DoStuffFunction, false);
    } else {
        window.attachEvent('onload',DoStuffFunction);
    }
}

答案 8 :(得分:1)

我有其他解决方案,我的应用程序需要在创建MyApp的新对象时启动,所以它看起来像:

function MyApp(objId){
     this.init=function(){
        //.........
     }
     this.run=function(){
          if(!document || !document.body || !window[objId]){
              window.setTimeout(objId+".run();",100);
              return;
          }
          this.init();
     };
     this.run();
}
//and i am starting it 
var app=new MyApp('app');

它适用于所有浏览器,我知道。