window.onload vs document.onload


712

Quale è più ampiamente supportato: window.onloado document.onload?


2
I documenti MDN spiegano questi windoweventi: onloade DOMContentLoaded. Esempio di utilizzo :, window.addEventListener('DOMContentLoaded', callback). A partire dalla metà del 2019, compatibile con tutti i principali browser. ----- developer.mozilla.org/en-US/docs/Web/API/Window/… ------ developer.mozilla.org/en-US/docs/Web/API/Window/load_event
Craig Hicks l'

Per me ancora, in Firefox 75.0 oggi, window.onloade document.onloadsono diversi l' uno dall'altro! window.onloadsembra avvenire in seguito e ha un po 'più caricato di document.onload! (Alcune cose funzionano con una finestra che non funziona con il documento! Questo vale anche per document.onreadstatechange 'complete'!)
Andrew

Risposte:


723

Quando sparano?

window.onload

  • Per impostazione predefinita, viene attivato quando viene caricata l'intera pagina, incluso il suo contenuto (immagini, CSS, script, ecc.).

In alcuni browser ora assume il ruolo document.onloade si attiva anche quando il DOM è pronto.

document.onload

  • Viene chiamato quando il DOM è pronto, che può essere precedente alle immagini e viene caricato altro contenuto esterno.

Quanto bene sono supportati?

window.onloadsembra essere il più ampiamente supportato. In effetti, alcuni dei browser più moderni sono stati in qualche modo sostituiti document.onloadda window.onload.

I problemi di supporto del browser sono probabilmente il motivo per cui molte persone stanno iniziando a utilizzare librerie come jQuery per gestire il controllo del documento pronto, in questo modo:

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

Ai fini della storia. window.onloadvs body.onload:

Una domanda simile è stata posta sui codingforum qualche tempo fa riguardo all'uso di window.onloadover body.onload. Il risultato sembrava essere che dovresti usare window.onloadperché è bene separare la tua struttura dall'azione.


25
In realtà questa affermazione sembra essere diretta a una scelta tra window.onloade <body onload="">che è completamente diversa (e la "struttura separata dall'azione" ha molto più senso in questo contesto). Non che la risposta sia sbagliata, ma la base è.
Thor84no,

2
Quella citazione è grammaticalmente orribile ... non dovrebbe aiutare qualche modifica (contrassegnata)?
Kheldar,

@ Thor84no Finalmente ho trovato il tempo di dare un'occhiata a questo. Ho apportato alcuni miglioramenti.
Josh Mein,

@Kheldar Ho deciso di parafrasare la citazione poiché era piuttosto approssimativa.
Josh Mein,

@JoshMein Significa che document.onloadè l'equivalente JS di jQuery document.ready?
john cj,

276

L'idea generale è che gli incendi window.onload quando la finestra del documento è pronto per la presentazione e document.onload incendi quando il DOM (costruito dal codice di markup all'interno del documento) è completata .

Idealmente, l'abbonamento agli eventi della struttura DOM , consente manipolazioni fuori schermo tramite Javascript, senza quasi alcun carico della CPU . Al contrario, window.onloadpuò richiedere del tempo per essere attivato , quando più risorse esterne devono ancora essere richieste, analizzate e caricate.

► Scenario di prova:

Per osservare la differenza e come il tuo browser preferito implementa i suddetti gestori di eventi , inserisci semplicemente il seguente codice nel <body>tag - - del tuo documento .

<script language="javascript">
window.tdiff = []; fred = function(a,b){return a-b;};
window.document.onload = function(e){ 
    console.log("document.onload", e, Date.now() ,window.tdiff,  
    (window.tdiff[0] = Date.now()) && window.tdiff.reduce(fred) ); 
}
window.onload = function(e){ 
    console.log("window.onload", e, Date.now() ,window.tdiff, 
    (window.tdiff[1] = Date.now()) && window.tdiff.reduce(fred) ); 
}
</script>

►Result:

Ecco il comportamento risultante, osservabile per Chrome v20 (e probabilmente la maggior parte dei browser attuali).

  • Nessun document.onloadevento
  • onloadspara due volte quando dichiarato all'interno del <body>, una volta quando dichiarato all'interno del <head>(dove l'evento agisce come document.onload).
  • contare e agire in base allo stato del contatore consente di emulare entrambi i comportamenti degli eventi.
  • In alternativa, dichiarare il window.onloadgestore eventi all'interno dei limiti <head>dell'elemento HTML .

►Esempio di progetto:

Il codice sopra è preso dalla base di codice di questo progetto ( index.htmle keyboarder.js).


Per un elenco dei gestori di eventi dell'oggetto finestra , fare riferimento alla documentazione MDN.


143

Aggiungi listener di eventi

<script type="text/javascript">
  document.addEventListener("DOMContentLoaded", function(event) {
      // - Code to execute when all DOM content is loaded. 
      // - including fonts, images, etc.
  });
</script>


Update March 2017

1 JavaScript vaniglia

window.addEventListener('load', function() {
    console.log('All assets are loaded')
})


2 jQuery

$(window).on('load', function() {
    console.log('All assets are loaded')
})


In bocca al lupo.


14
"L'evento DOMContentLoaded viene generato quando il documento HTML iniziale è stato completamente caricato e analizzato, senza attendere il completamento del caricamento di fogli di stile, immagini e sottoframe." - developer.mozilla.org/en/docs/Web/Events/DOMContentLoaded Quindi sembra che tu non sia corretto su tutto ciò che viene caricato in questo evento.
ProfK

2
@ProfK, grazie per il tuo feedback. Puoi provare window.addEventListener('load', function() {...}). Ho anche aggiornato la mia risposta.
Akash,

4
Quello che mi piace di questa risposta è che offre una soluzione javascript semplice. Penseresti che la maggior parte delle persone pensa che jQuery sia integrato in tutti i browser, data la frequenza con cui viene data come unica risposta.
Dave Land,

Doppio problema quando il dannato jquery impiega troppo tempo a caricarsi e ottieni $ non trovato. Sono dell'opinione che le soluzioni di tipo $ (window) .ready non debbano MAI essere affidabili per funzionare.
Shayne,

1
Ho provato entrambi nella versione cromata di oggi. Non sta aspettando CSS e font.
movAX13h,

78

Secondo l' analisi dei documenti HTML - The end ,

  1. Il browser analizza l'origine HTML ed esegue script posticipati.

  2. A DOMContentLoadedviene inviato documentquando tutto l'HTML è stato analizzato ed eseguito. L'evento bolle al window.

  3. Il browser carica risorse (come immagini) che ritardano l'evento di caricamento.

  4. Un loadevento viene inviato al window.

Pertanto, l'ordine di esecuzione sarà

  1. DOMContentLoadedascoltatori di eventi windownella fase di acquisizione
  2. DOMContentLoaded ascoltatori di eventi di document
  3. DOMContentLoadedascoltatori di eventi windownella fase a bolle
  4. loadlistener di eventi (incluso il onloadgestore di eventi) diwindow

Un loadlistener di eventi bubble (incluso il onloadgestore eventi) in documentnon dovrebbe mai essere invocato. loadPotrebbero essere invocati solo i listener di acquisizione , ma a causa del caricamento di una sotto-risorsa come un foglio di stile, non a causa del caricamento del documento stesso.

window.addEventListener('DOMContentLoaded', function() {
  console.log('window - DOMContentLoaded - capture'); // 1st
}, true);
document.addEventListener('DOMContentLoaded', function() {
  console.log('document - DOMContentLoaded - capture'); // 2nd
}, true);
document.addEventListener('DOMContentLoaded', function() {
  console.log('document - DOMContentLoaded - bubble'); // 2nd
});
window.addEventListener('DOMContentLoaded', function() {
  console.log('window - DOMContentLoaded - bubble'); // 3rd
});

window.addEventListener('load', function() {
  console.log('window - load - capture'); // 4th
}, true);
document.addEventListener('load', function(e) {
  /* Filter out load events not related to the document */
  if(['style','script'].indexOf(e.target.tagName.toLowerCase()) < 0)
    console.log('document - load - capture'); // DOES NOT HAPPEN
}, true);
document.addEventListener('load', function() {
  console.log('document - load - bubble'); // DOES NOT HAPPEN
});
window.addEventListener('load', function() {
  console.log('window - load - bubble'); // 4th
});

window.onload = function() {
  console.log('window - onload'); // 4th
};
document.onload = function() {
  console.log('document - onload'); // DOES NOT HAPPEN
};


Ho eseguito il tuo frammento e in document - load - captureeffetti succede, il che è in contrasto con quello che mi aspettavo nella mia ricerca sul motivo per cui il caricamento del documento non sta avvenendo per me. Stranamente, è incoerente. A volte appare, a volte no, a volte appare due volte - ma non succede mai document - load - bubble. Suggerirei di non usare document load.
errore

@erroric Buon punto. Non ho considerato che un loadevento viene inviato su risorse esterne. Tale evento non crea bolle, quindi di solito non viene rilevato sul documento, ma dovrebbe essere in fase di acquisizione. Queste voci si riferiscono al carico degli elementi <style>e <script>. Penso che Edge abbia ragione per mostrarli e Firefox e Chrome siano sbagliati.
Oriol

Grazie Oriol, l' useCaptureopzione mi ha insegnato qualcosa di nuovo.
Paul Watson,

Grazie per aver riassunto il flusso di analisi e rendering da w3. Mi chiedo solo dopo il passaggio 4, una volta che l'evento "load" è stato attivato, cos'altro può succedere? Ho notato sul mio browser che a volte ci sono ancora alcuni oggetti che vengono recuperati dopo che l'evento load è stato attivato anche se non ho toccato o interagito con la pagina. Sai come si chiamano quegli oggetti? 'Oggetti di rendering non bloccanti?
weefwefwqg3,

12

In Chrome, window.onload è diverso da <body onload="">, mentre sono uguali in Firefox (versione 35.0) e IE (versione 11).

Puoi esplorarlo con il seguente frammento:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <!--import css here-->
        <!--import js scripts here-->

        <script language="javascript">

            function bodyOnloadHandler() {
                console.log("body onload");
            }

            window.onload = function(e) {
                console.log("window loaded");
            };
        </script>
    </head>

    <body onload="bodyOnloadHandler()">

        Page contents go here.

    </body>
</html>

E vedrai sia "Window Loaded" (che viene in primo luogo) che "Body Onload" nella console di Chrome. Tuttavia, vedrai solo "body onload" in Firefox e IE. Se esegui " window.onload.toString()" nelle console di IE e FF, vedrai:

"function onload (event) {bodyOnloadHandler ()}"

il che significa che l'assegnazione "window.onload = function (e) ..." viene sovrascritta.


6

window.onloade onunloadsono scorciatoie per document.body.onloadedocument.body.onunload

document.onloade il onloadgestore su tutti i tag html sembra essere riservato, ma mai attivato

' onload' nel documento -> vero


5

window.onload tuttavia sono spesso la stessa cosa. Allo stesso modo body.onload diventa window.onload in IE.


1

Window.onload è lo standard, tuttavia: il browser Web in PS3 (basato su Netfront) non supporta l'oggetto finestra, quindi non è possibile utilizzarlo lì.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.