[英]How to tell whether the $(window).load()/window.onload event has already fired?
[英]How to know if window "load" event was fired already
我正在编写一个 Javascript 脚本。 该脚本可能会异步加载(AMD 格式)。
在这个脚本中,在window.load
事件被触发之前,我不想做任何重要的事情。 所以我听窗口“加载”事件。
但是如果脚本是在 window.load 事件之后加载的……我怎么知道window.load
已经被触发了?
当然我不想在任何其他脚本中添加一些东西(它们都是异步加载的,问题是一样的):)
编辑 :
想象一个完全没有 Javascript 的 HTML 文档。
比有人在这个文档中插入一个标签,这个脚本标签加载我的 Javascript 文件。
这将执行我的脚本。
这个脚本如何知道 window.load 是否已经被触发?
没有 jQuery,在我之前的 HTML 文档中没有任何脚本。
有可能知道吗??
我找到了window.document.readystate
属性。 我猜这个属性是针对文档“就绪”事件,而不是针对窗口“加载”。 窗口“加载”事件有类似的东西吗?
最简单的解决方案可能是检查document.readyState == 'complete'
,请参阅http://www.w3schools.com/jsref/prop_doc_readystate.asp
要快速回答问题的标题:
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
。 如果您现在为此窗口将相同的内容放入控制台,它应该评估为真。
另请参阅: '$(document).ready()' 的非 jQuery 等价物是什么?
Igor 在评论中提出了一个有趣的问题,下面的代码可以尝试在尽力超时的情况下处理该问题。
问题是document.readyState
可以在load
事件触发之前complete
。 我不确定这可能会导致什么潜在问题。
Complete: The state indicates that the load event is about to fire.
给出了一个事件触发的实例,即:
- 就绪状态:
interactive
- 事件触发:
DOMContentLoaded
- 就绪状态:
complete
- 事件触发:
load
在load
触发之前, readyState
可能会在短时间内complete
。 我不确定您在此期间可能会遇到什么问题。
下面的代码注册了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'); });
浏览器导航性能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');
}
这是我的答案:
window.addEventListener("load", function () {
window.loaded = true;
});
function logLoaded() {
console.log("loaded");
}
(function listen () {
if (window.loaded) {
logLoaded();
} else {
console.log("notLoaded");
window.setTimeout(listen, 50);
}
})();
您可以在此处阅读addEventListener()及其兼容性(它是ECMAScript 5规范的新增内容)。 这是未来做事的新“首选”方式。
你可以阅读有关立即调用函数表达式(IIFE)(交替,自我援引匿名函数或立即调用匿名函数) 这里 。
编辑:这是StackOverflow上的一个很好的答案:
如果您特别想知道DOM加载事件是否已触发,请在DOM“load”事件处理程序中设置一个全局变量,然后在加载新代码时检查它是否存在。
// in 'load' event handler
window.domLoadEventFired = true;
// in code you are loading asynchronously
if (typeof window.domLoadEventFired !== undefined) {
// ...
}
如果你不想使用 jQuery,它使用的逻辑是:
if( !document.body )
setTimeout( checkAgain, 1 );
因此,在 windows 加载事件和检查文档的 body 属性是否可用之间,您可以检查 DOM 是否准备好
基于@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.load怎么样?
window._load = window.load;
window.load = function(){
window.loaded = true;
window._load();
}
然后检查
if (window.loaded != undefined && window.loaded == true){
//do stuff
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.