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

Mar*_*cos 157 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

lau*_*ent 249

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

if (document.readyState === "complete") { init(); }
Run Code Online (Sandbox Code Playgroud)

这也是jQuery如何做到的.

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

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

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

在文档加载时返回"加载",在完成解析但仍加载子资源时返回"交互",并在加载后"完成".- Mozilla Developer Network的document.readyState

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

  • @costa,如果`document.readyState =="完成"`,则表示已加载所有内容,包括图像. (3认同)
  • 我使用```/ loaded|complete/.test(document.readyState)```.有些浏览器将```document.readyState```设置为"loaded"而不是"complete".另外,document.readyState不能确保加载字体,没有插件就没有真正好的方法来测试它. (2认同)
  • 怎么样`document.onreadystatechange`?如果浏览器支持它,这似乎更精简.http://stackoverflow.com/questions/807878/javascript-that-executes-after-page-load/25786528#25786528 (2认同)
  • 我认为最好检查`document.readyState!=="loading"`,以获取"DOM ready"状态.如果由于某种原因(在"交互"状态之后)检查`readyState`,则可以防止出现问题. (2认同)

gbl*_*zex 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;
Run Code Online (Sandbox Code Playgroud)

  • 完全错过了问题的重点.如果您发布的代码包含在页面已经加载之后,`init`将不会运行,这是OP的要点:他/她无法控制何时包含其脚本.(注意只有`setInterval`分支才能工作) (3认同)
  • 这属于图书馆.与所有其他车轮一起,人们通常会重新发明. (3认同)

小智 15

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

就像是:

$(document).ready(function(){
   // Your code here
});
Run Code Online (Sandbox Code Playgroud)

似乎做你想做的事.

  • -1:即使答案有意义,OP也从未提及过jQuery.使用整个jQuery项目只是为了准备文档是有点矫枉过正. (32认同)
  • 如果不清楚,如果在*文档加载后调用*ready()`,则立即运行传递的函数. (6认同)
  • 如果他想看看jQuery如何以可移植的方式做到这一点,那么jQuery的来源就是检查:-) (2认同)
  • @Ben Blank:除非在文档加载后当然包括jQuery本身,否则) (2认同)

Jma*_*man 6

if(document.readyState === 'complete') {
    DoStuffFunction();
} else {
    if (window.addEventListener) {  
        window.addEventListener('load', DoStuffFunction, false);
    } else {
        window.attachEvent('onload', DoStuffFunction);
    }
}
Run Code Online (Sandbox Code Playgroud)


Nat*_*tch 5

如果你真的希望这个代码在加载时运行,而不是在domready 上运行(即你需要加载图像),那么遗憾的是,ready函数不会为你做.我通常只做这样的事情:

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

var pageisloaded=0;
window.addEvent('load',function(){
 pageisloaded=1;
});
Run Code Online (Sandbox Code Playgroud)

然后你的代码:

if (pageisloaded) {
 DoStuffFunction();
} else {
 window.addEvent('load',DoStuffFunction);
}
Run Code Online (Sandbox Code Playgroud)

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

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