簡體   English   中英

如何知道窗口“加載”事件是否已經觸發

[英]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 等價物是什么?


通過評論處理來自@IgorBykov 的邊緣案例

Igor 在評論中提出了一個有趣的問題,下面的代碼可以嘗試在盡力超時的情況下處理該問題。

問題是document.readyState可以在load事件觸發之前complete 我不確定這可能會導致什么潛在問題。

關於流程和事件觸發的一些文檔

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

給出了一個事件觸發的實例,即:

  1. 就緒狀態: interactive
  2. 事件觸發: DOMContentLoaded
  3. 就緒狀態: complete
  4. 事件觸發: 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加載事件是否已觸發,請在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.onload = (event) => {
  console.log('page is fully loaded');
};

您可以從這里的資源中找到其他方法。

覆蓋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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM