如何知道窗口“加载”事件是否已经激发

我在写一个 Javascript 脚本。 这个脚本可能会被异步加载(AMD 格式)。

在这个脚本中,我希望在触发 window.load事件之前不做任何重要的事情。 因此,我监听窗口“ load”事件。

但是如果脚本是在 window.load 事件之后加载的... ... 我怎么知道 window.load已经被激活了呢?

当然,我不想在任何其他脚本中添加任何东西(它们都是异步加载的,问题是一样的) :)

编辑:

想象一下,一个 HTML 文档中根本没有 Javascript。

在这个文档中插入一个标记,然后这个脚本标记加载我的 Javascript 文件。

这将执行我的脚本。

这个脚本如何知道 window.load 是否已经被激活?

没有 jQuery,在我之前的 HTML 文档中没有任何脚本。

有可能知道吗?

我找到了 window.document.readystate属性。我猜这个属性是用于文档“就绪”事件的,而不是用于窗口“加载”。 窗口“加载”事件有类似的情况吗?

46335 次浏览

重写 windows load 怎么样?

window._load = window.load;
window.load = function(){
window.loaded = true;
window._load();
}

那就检查一下

if (window.loaded != undefined && window.loaded == true){
//do stuff
}

如果你不想使用 jQuery,它的逻辑是:

if( !document.body )
setTimeout( checkAgain, 1 );

因此,在加载的窗口事件和检查文档的 body 属性是否可用之间,您可以检查 DOM 是否准备好了

最简单的解决方案可能是检查 document.readyState == 'complete',请参阅 http://www.w3schools.com/jsref/prop_doc_readystate.asp

Browser 导航性能 loadEventEnd 指标可用于确定是否触发了加载事件:

let navData = window.performance.getEntriesByType("navigation");
if (navData.length > 0 && navData[0].loadEventEnd > 0)
{
console.log('Document is loaded');
} else {
console.log('Document is not loaded');
}

快速回答

快速回答问题的题目:

document.readyState === 'complete'

更深层次的例子

如果您希望在加载窗口时调用代码,同时仍然处理在代码运行时窗口可能已经加载的情况,下面是一个很好的帮助器。

function winLoad(callback) {
if (document.readyState === 'complete') {
callback();
} else {
window.addEventListener("load", callback);
}
}


winLoad(function() {
console.log('Window is loaded');
});

注意 : 这里的代码片段实际上不在相同的窗口上下文中运行,因此当您运行这个代码时,document.readyState === 'complete'实际上计算为 false。如果你现在把同样的东西放到你的控制台上,这个窗口的值应该是 true。

参见: 什么是非 jQuery 等同于 & # 39; $(document) . ready () & # 39;?


通过注释处理@IgorBykov 的边缘情况

Igor 在注释中提出了一个有趣的问题,下面的代码可以在给定最佳努力超时的情况下尝试处理这个问题。

问题是在 load事件发生之前,document.readyState可以是 complete。我不确定这会引起什么潜在的问题。

关于流动与事件发生的一些文献

Complete: The state indicates that the load event is about to fire.

给出一个事件触发的实例:

  1. ReadyState: interactive
  2. 事件发生: DOMContentLoaded
  3. ReadyState: complete
  4. 事件发生: load

有一个短暂的时刻,在 readyState可能是 complete之前,load发射。我不知道在这段时间里你会遇到什么问题。

下面的代码注册 load事件侦听器,并设置一个超时来检查 readyState。默认情况下,在检查 readyState之前它将等待200毫秒。如果 load事件在 timeout之前触发,我们要确保防止再次触发回调。如果我们到了 timeout的末尾,而 load没有被触发,我们检查 readyState,并确保避免 load事件可能在以后触发的情况。

根据您试图完成的任务,您可能希望无论如何都运行 load回调(删除 if (!called) {检查)。在回调中,您可能希望将潜在代码包装在 try/catch 语句中,或者检查一些可以关闭执行的内容,以便当它调用两次时,只有在所有内容都可用时才执行工作。

function winLoad(callback, timeout = 200) {
let called = false;


window.addEventListener("load", () => {
if (!called) {
called = true;
callback();
}
});


setTimeout(() => {
if (!called && document.readyState === 'complete') {
called = true;
callback();
}
}, timeout);
}


winLoad(function() {
console.log('Window is loaded');
});

基于@CTS _ AE 的方法,我整合了一个环境解决方案:

  • window.addEventListener('load', activateMyFunction);
  • window.addEventListener('DOMContentLoaded', activateMyFunction);

没用。

它需要单个字符替换(例如从

window.addEventListener('load', activateMyFunction);

window_addEventListener('load', activateMyFunction);)

函数 window_addEventListener()如下:

const window_addEventListener = (eventName, callback, useCapture = false) => {


if ((document.readyState === 'interactive') || (document.readyState === 'complete'))   {


callback();
}
}

简单方法:

window.onload = (event) => {
console.log('page is fully loaded');
};

您可以从资源 给你中找到其他方法。