window.onload vs document.onload

710

Welches wird allgemeiner unterstützt: window.onloadoder document.onload?

Chris Ballance
quelle
2
MDN-Dokumente erläutern diese windowEreignisse: onloadund DOMContentLoaded. Anwendungsbeispiel:, window.addEventListener('DOMContentLoaded', callback). Ab Mitte 2019 kompatibel mit allen gängigen Browsern. ----- developer.mozilla.org/en-US/docs/Web/API/Window/… ------ developer.mozilla.org/en-US/docs/Web/API/Window/load_event
Craig Hicks
Für mich auch noch, in Firefox 75.0 heute, window.onloadund document.onloadsind verschieden voneinander! window.onloadscheint danach zu stattfinden und hat etwas mehr geladen als document.onload! (Einige Dinge funktionieren mit Fenstern, die nicht mit Dokumenten funktionieren! Dies gilt auch für document.onreadstatechange 'complete'!)
Andrew

Antworten:

722

Wann schießen sie?

window.onload

  • Standardmäßig wird es ausgelöst, wenn die gesamte Seite einschließlich ihres Inhalts (Bilder, CSS, Skripte usw.) geladen wird.

In einigen Browsern übernimmt es jetzt die Rolle von document.onloadund wird ausgelöst, wenn das DOM ebenfalls bereit ist.

document.onload

  • Es wird aufgerufen, wenn das DOM bereit ist, bevor Bilder und andere externe Inhalte geladen werden können.

Wie gut werden sie unterstützt?

window.onloadscheint am weitesten verbreitet zu sein. In der Tat haben einige der meisten modernen Browser in ein Gefühl ersetzt document.onloadmit window.onload.

Probleme mit der Browserunterstützung sind höchstwahrscheinlich der Grund, warum viele Benutzer Bibliotheken wie jQuery verwenden , um die Überprüfung des bereitstehenden Dokuments durchzuführen.

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

Zum Zweck der Geschichte. window.onloadvs body.onload:

Eine ähnliche Frage wurde vor einiger Zeit in Codierungsforen bezüglich der Verwendung von window.onloadover gestellt body.onload. Das Ergebnis schien zu sein, dass Sie verwenden sollten, window.onloadweil es gut ist, Ihre Struktur von der Aktion zu trennen.

Josh Mein
quelle
25
Tatsächlich scheint diese Aussage auf eine Wahl zwischen window.onloadund <body onload="">völlig anders gerichtet zu sein (und die "von der Handlung getrennte Struktur" ist in diesem Zusammenhang viel sinnvoller). Nicht dass die Antwort falsch ist, aber die Grundlage dafür ist.
Thor84no
2
Dieses Zitat ist grammatikalisch schrecklich ... sollte nicht eine (markierte) Bearbeitung helfen?
Kheldar
@ Thor84no Ich habe endlich die Zeit gefunden, mir das noch einmal anzuschauen. Ich habe einige Verbesserungen vorgenommen.
Josh Mein
@Kheldar Ich habe beschlossen, das Zitat zu paraphrasieren, da es ziemlich rau war.
Josh Mein
@JoshMein Bedeutet das, dass document.onloadJS-Äquivalent zu jQuery ist document.ready?
John CJ
276

Die allgemeine Idee ist, dass window.onload ausgelöst wird, wenn das Fenster des Dokuments zur Präsentation bereit ist, und document.onload ausgelöst wird, wenn der DOM-Baum (erstellt aus dem Markup-Code im Dokument) abgeschlossen ist .

Im Idealfall ermöglicht das Abonnieren von DOM-Tree-Ereignissen Offscreen-Manipulationen über Javascript, wobei fast keine CPU-Last anfällt . Im Gegensatz dazu window.onloadkann das Feuern eine Weile dauern , wenn noch mehrere externe Ressourcen angefordert, analysiert und geladen werden müssen.

►Testszenario:

Um den Unterschied und zu beobachten , wie Sie Ihren Browser der Wahl implementiert die oben genannten Event - Handler , legen Sie einfach den folgenden Code innerhalb Ihres Dokuments - <body>- tag.

<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>

►Ergebnis:

Hier ist das resultierende Verhalten, das für Chrome v20 (und wahrscheinlich die meisten aktuellen Browser) zu beobachten ist.

  • Kein document.onloadEreignis.
  • onloadwird zweimal ausgelöst <body>, wenn es innerhalb von deklariert wird , einmal, wenn es innerhalb von deklariert wird <head>(wobei das Ereignis dann als fungiert document.onload).
  • Durch Zählen und Handeln in Abhängigkeit vom Status des Zählers können beide Ereignisverhalten emuliert werden.
  • Alternativ können Sie den window.onloadEreignishandler innerhalb der Grenzen des HTML- <head>Elements deklarieren .

►Beispielprojekt:

Der obige Code stammt aus der Codebasis ( index.htmlund keyboarder.js) dieses Projekts .


Eine Liste der Ereignishandler des Fensterobjekts finden Sie in der MDN-Dokumentation.

Lorenz Lo Sauer
quelle
142

Ereignis-Listener hinzufügen

<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 Vanille-JavaScript

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


2 jQuery

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


Viel Glück.

Akash
quelle
14
"Das DOMContentLoaded-Ereignis wird ausgelöst, wenn das ursprüngliche HTML-Dokument vollständig geladen und analysiert wurde, ohne darauf zu warten, dass Stylesheets, Bilder und Subframes vollständig geladen werden." - developer.mozilla.org/en/docs/Web/Events/DOMContentLoaded Sie scheinen also falsch zu sein, wenn bei diesem Ereignis alles geladen wird.
ProfK
2
@ProfK, vielen Dank für Ihr Feedback. Können Sie versuchen window.addEventListener('load', function() {...}). Ich habe auch meine Antwort aktualisiert.
Akash
4
Was mir an dieser Antwort gefällt, ist, dass sie eine einfache, alte Javascript-Lösung bietet. Man könnte meinen, dass die meisten Leute denken, dass jQuery in alle Browser integriert ist, wenn man bedenkt, wie oft es als einzige Antwort angegeben wird.
Dave Land
Doppeltes Problem, wenn das Laden der verdammten Abfrage zu lange dauert und Sie $ nicht gefunden bekommen. Ich bin der Meinung, dass den Lösungen vom Typ $ (Fenster) .ready NIEMALS vertraut werden sollte, dass sie funktionieren.
Shayne
1
Ich habe beide in heutigem Chrom ausprobiert. Es wartet nicht auf CSS und Schriftarten.
movAX13h
78

Laut Parsing HTML-Dokumente - Das Ende ,

  1. Der Browser analysiert die HTML-Quelle und führt verzögerte Skripte aus.

  2. A DOMContentLoadedwird zu dem documentZeitpunkt versendet, an dem der gesamte HTML-Code analysiert und ausgeführt wurde. Das Ereignis sprudelt zum window.

  3. Der Browser lädt Ressourcen (wie Bilder), die das Ladeereignis verzögern.

  4. Eine loadVeranstaltung wird am versandt window.

Daher wird die Ausführungsreihenfolge sein

  1. DOMContentLoadedEreignis-Listener von windowin der Erfassungsphase
  2. DOMContentLoaded Event-Listener von document
  3. DOMContentLoadedEvent-Listener windowin der Bubble-Phase
  4. loadEreignis-Listener (einschließlich onloadEreignishandler) vonwindow

Ein Bubble- loadEvent-Listener (einschließlich onloadEvent-Handler) in documentsollte niemals aufgerufen werden. loadMöglicherweise werden nur Capture- Listener aufgerufen, jedoch aufgrund des Ladens einer Unterressource wie eines Stylesheets und nicht aufgrund des Ladens des Dokuments.

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
};

Oriol
quelle
Ich habe Ihr Snippet ausgeführt und es document - load - capturepassiert tatsächlich, was im Widerspruch zu dem steht, was ich bei meiner Suche erwartet hatte, warum das Laden von Dokumenten für mich nicht erfolgt. Seltsamerweise ist es inkonsistent. Manchmal erscheint es, manchmal nicht, manchmal erscheint es zweimal - aber es document - load - bubblepassiert nie . Ich würde vorschlagen, nicht zu verwenden document load.
fehlerhafter
@erroric Guter Punkt. Ich habe nicht berücksichtigt, dass ein loadEreignis auf externen Ressourcen ausgelöst wird. Dieses Ereignis sprudelt nicht, sodass es normalerweise nicht im Dokument erkannt wird, es sollte sich jedoch in der Erfassungsphase befinden. Diese Einträge beziehen sich auf die Last der Elemente <style>und <script>. Ich denke, Edge ist richtig, um sie zu zeigen, und Firefox und Chrome sind falsch.
Oriol
Danke Oriol, die useCaptureOption hat mir etwas Neues beigebracht.
Paul Watson
Vielen Dank, dass Sie den Parsing- und Rendering-Ablauf von w3 zusammengefasst haben. Ich frage mich nur, was nach Schritt 4 nach dem Auslösen des Ladeereignisses noch passieren kann. In meinem Browser ist mir aufgefallen, dass nach dem Auslösen des Ladeereignisses manchmal noch einige Objekte abgerufen werden, obwohl ich die Seite überhaupt nicht berührt oder mit ihr interagiert habe. Wissen Sie, wie diese Objekte heißen? 'Nicht blockierende Rendering-Objekte?
weefwefwqg3
12

In Chrome unterscheidet sich window.onload von <body onload="">, während sie in Firefox (Version 35.0) und IE (Version 11) identisch sind.

Sie können dies anhand des folgenden Ausschnitts untersuchen:

<!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>

Und Sie werden sowohl "Fenster geladen" (was zuerst kommt) als auch "Body Onload" in der Chrome-Konsole sehen. In Firefox und IE wird jedoch nur "Body Onload" angezeigt. Wenn Sie " window.onload.toString()" in den Konsolen von IE & FF ausführen , sehen Sie:

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

was bedeutet, dass die Zuordnung "window.onload = function (e) ..." überschrieben wird.

VincentZHANG
quelle
6

window.onloadund onunloadsind Verknüpfungen zu document.body.onloadunddocument.body.onunload

document.onloadund der onloadHandler für alle HTML-Tags scheint reserviert zu sein, wird jedoch nie ausgelöst

' onload' im Dokument -> wahr

Garaboncias
quelle
5

window.onload sind jedoch oft dasselbe. In ähnlicher Weise wird body.onload im IE zu window.onload.

AnthonyWJones
quelle
1

Window.onload ist jedoch der Standard - der Webbrowser in der PS3 (basierend auf Netfront) unterstützt das Fensterobjekt nicht, sodass Sie es dort nicht verwenden können.

gotofritz
quelle
0

Zusamenfassend

Kamil Kiełczewski
quelle