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

IT技术 javascript events onload addeventlistener
2021-01-14 09:41:14

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

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);
    }
}
6个回答

不需要 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可以有三种状态:

在文档加载时返回“正在加载”,在完成解析但仍在加载子资源后返回“交互”,并在加载后返回“完成”。-- Mozilla 开发者网络上的 document.readyState

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

@costa,如果document.readyState == "complete",则意味着所有内容,包括图像,都已加载。
2021-03-13 09:41:14
怎么样document.onreadystatechange如果浏览器支持,这似乎更简化。stackoverflow.com/questions/807878/...
2021-03-13 09:41:14
我会用/loaded|complete/.test(document.readyState). 一些浏览器设置document.readyState为“加载”而不是“完成”。此外,document.readyState 不能确保已加载字体,没有插件就没有真正的好方法来测试它。
2021-03-27 09:41:14
我正在使用这两个事件的组合,并document.readyState确保函数在解析 DOM 之后启动,或者稍后启动,具体取决于它何时被调用。互动 活动readyState吗?
2021-04-02 09:41:14
我认为最好检查document.readyState !== "loading", 以了解“DOM 就绪”状态。如果由于readyState某种原因(在“交互式”状态之后)检查延迟,这可以防止出现问题
2021-04-03 09:41:14

不需要图书馆。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;
这属于图书馆。人们通常会重新发明所有其他轮子。
2021-03-13 09:41:14
完全错过了问题的重点。init如果在页面加载后包含您发布的此代码,则不会运行,这就是 OP 的重点:他/她无法控制何时包含他的脚本。(请注意,只有setInterval分支才能工作)
2021-03-30 09:41:14
正是我正在寻找的 - 没有 jQuery 库的 jQuery.ready 函数。谢谢!
2021-04-05 09:41:14

您可能想使用 jQuery 之类的东西,它使 JS 编程更容易。

就像是:

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

似乎会做你所追求的。

如果不清楚,如果文档加载ready()调用,则立即运行传递的函数。
2021-03-15 09:41:14
@Ben Blank:当然,除非在文档加载后包含 jQuery 本身;)
2021-03-15 09:41:14
@Roatin Marth — 实际上,这也很好用。(刚在 FF8 和 IE8 上用 jQuery 1.7.1 试过。)
2021-03-22 09:41:14
-1:即使答案有道理,OP 也从未提及 jQuery。使用整个 jQuery 项目只是为了准备好文档是一种矫枉过正的方式。
2021-03-27 09:41:14
如果他想看看 jQuery 如何以可移植的方式做到这一点,可以查看 jQuery 的源代码:-)
2021-03-30 09:41:14
if(document.readyState === 'complete') {
    DoStuffFunction();
} else {
    if (window.addEventListener) {  
        window.addEventListener('load', DoStuffFunction, false);
    } else {
        window.attachEvent('onload', DoStuffFunction);
    }
}
似乎在最新的 Chrome 中不起作用document.loaded始终未定义
2021-03-12 09:41:14
这是 2010 年:)。现在我会用body.readyState === 'loaded'
2021-03-25 09:41:14

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

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

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

然后你的代码:

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

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

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