![](/img/trans.png)
[英]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.