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

Javascript-如何检测文档是否已加载(IE 7/Firefox 3),javascript,events,onload,addeventlistener,Javascript,Events,Onload,Addeventlistener,我想在加载文档后调用函数,但文档可能已经加载完毕,也可能尚未加载完毕。如果它确实加载了,那么我可以调用这个函数。如果没有加载,那么我可以附加一个事件侦听器。我无法在onload启动后添加eventlistener,因为它不会被调用。那么如何检查文档是否已加载?我尝试了下面的代码,但并不完全有效。有什么想法吗 var body = document.getElementsByTagName('BODY')[0]; // CONDITION DOES NOT WORK if (body &&

我想在加载文档后调用函数,但文档可能已经加载完毕,也可能尚未加载完毕。如果它确实加载了,那么我可以调用这个函数。如果没有加载,那么我可以附加一个事件侦听器。我无法在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);
    }
}

您可能希望使用类似jQuery的东西,这使得JS编程更容易

比如:

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

如果您确实希望此代码在加载时运行,而不是在domready(即您也需要加载图像)时运行,那么很遗憾,ready函数不适合您。我通常只是这样做:

包含在文档javascript中(即总是在启动onload之前调用):

然后您的代码:

if (pageisloaded) {
 DoStuffFunction();
} else {
 window.addEvent('load',DoStuffFunction);
}
(或您偏好的框架中的等效代码)我使用此代码为将来的页面预编译javascript和图像。因为我得到的东西根本不用于这个页面,我不希望它优先于快速下载图片


也许有更好的方法,但我还没有找到。

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

//迪安·爱德华兹/马蒂亚斯·米勒/约翰·雷斯格
函数init(){
//如果已调用此函数,请退出
if(arguments.callee.done)返回;
//标记这个函数,这样我们就不会做同样的事情两次
arguments.callee.done=true;
//停止计时
如果(_定时器)清除间隔(_定时器);
//做事
};
/*用于Mozilla/Opera9*/
if(文件增补列表器){
document.addEventListener(“DOMContentLoaded”,init,false);
}
/*用于Internet Explorer*/
/*@抄送@*/
/*@如果(@_win32)
文件。填写(“”);
var script=document.getElementById(“\uu ie\u onload”);
script.onreadystatechange=函数(){
如果(this.readyState==“完成”){
init();//调用onload处理程序
}
};
/*@结束@*/
/*狩猎旅行*/
if(/WebKit/i.test(navigator.userAgent)){//sniff
var_timer=setInterval(函数(){
如果(/loaded | complete/.test(document.readyState)){
init();//调用onload处理程序
}
}, 10);
}
/*对于其他浏览器*/
window.onload=init;

不需要galambalazs提到的所有代码。在纯JavaScript中使用跨浏览器的方法只是测试
文档。readyState

if (document.readyState === "complete") { init(); }
jQuery也是这样做的

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

var readyStateCheckInterval = setInterval(function() {
    if (document.readyState === "complete") {
        clearInterval(readyStateCheckInterval);
        init();
    }
}, 10);
实际上,
document.readyState
可以有三种状态:

在加载文档时返回“loading”,在完成解析但仍在加载子资源时返回“interactive”,在加载后返回“complete”。 --


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

以上使用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);

}

我有其他解决方案,我的应用程序需要在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');
据我所知,它适用于所有浏览器。

试试以下方法:

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

Mozila Firefox表示,
onreadystatechange
DOMContentLoaded
的替代品

// alternative to DOMContentLoaded
document.onreadystatechange = function () {
    if (document.readyState == "complete") {
        initApplication();
    }
}
DOMContentLoaded
中,Mozila的文档说:

DOMContentLoaded事件在文档已加载时激发 完全加载和解析,无需等待样式表、图像, 以及完成加载的子帧(加载事件可用于检测 完全加载的页面)


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

“我想在文档加载后调用函数,但文档可能已经加载完毕,也可能尚未加载完毕。”这不算。我相信他的意思是他无法控制代码块最初运行的时间,但是他想确保在文档加载完成之前没有调用DoStuffFunction()。如果他想看看jQuery是如何以可移植的方式运行的,jQuery的源代码就在那里进行检查:-),如果不清楚,在文档加载之后是否调用了
ready()
,传递的函数立即运行。@Ben Blank:当然,除非在加载文档后包含jQuery本身;)@罗汀·马思——事实上,这也很好用。(只是在FF8和IE8上用jQuery1.7.1进行了尝试。)-1:即使答案有道理,OP也从未提到过jQuery。使用整个jQuery项目只是为了准备好文档,这太过分了。这正是我想要的没有jQuery库的-jQuery.ready函数。塔克斯!完全没有抓住问题的要害<代码>初始化将不会运行,如果您发布的代码在页面加载后被包含,这就是操作的要点:他/她无法控制脚本何时被包含。(请注意,只有
setInterval
分支可以工作)这属于库。与人们通常重新发明的所有其他轮子一样。@costa,如果
document.readyState==“complete”
,这意味着包括图像在内的所有东西都已加载。我将同时使用事件和
document.readyState
来确保函数在解析DOM后或以后启动,取决于调用它的时间。交互式
readyState
是否有事件?我会使用
/loaded | complete/.test(document.readyState)
。某些浏览器设置
document.readyState
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');
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);
    }
}
// alternative to DOMContentLoaded
document.onreadystatechange = function () {
    if (document.readyState == "complete") {
        initApplication();
    }
}