Ich möchte ein bisschen Javascript ausführen, bevor die ganze Seite geladen ist. Ist das möglich? Oder beginnt die Ausführung des Codes </html>
?
javascript
html
Picknick
quelle
quelle
Antworten:
Nicht nur können Sie, aber Sie müssen eine besondere Anstrengungen unternehmen , um nicht zu , wenn Sie nicht wollen. :-)
Wenn der Browser
script
beim Parsen des HTML- Codes auf ein klassisches Tag stößt , stoppt er das Parsen und übergibt es dem JavaScript-Interpreter, der das Skript ausführt. Der Parser wird erst fortgesetzt, wenn die Skriptausführung abgeschlossen ist (da das Skript möglicherweisedocument.write
Aufrufe zum Ausgeben von Markups ausführt, die der Parser verarbeiten soll).Dies ist das Standardverhalten, aber Sie haben einige Optionen, um die Skriptausführung zu verzögern:
Verwenden Sie JavaScript-Module. Ein
type="module"
Skript wird verschoben , bis das HTML vollständig analysiert und die ursprüngliche DOM erstellt wurde. Dies ist nicht der Hauptgrund für die Verwendung von Modulen, aber einer der Gründe:Der Code wird abgerufen (sofern er separat ist) und parallel zur HTML-Analyse analysiert, jedoch erst ausgeführt, wenn die HTML-Analyse abgeschlossen ist. (Wenn Ihr Modulcode nicht in einer eigenen Datei, sondern inline ist, wird er ebenfalls zurückgestellt, bis die HTML-Analyse abgeschlossen ist.)
Dies war nicht verfügbar, als ich diese Antwort 2010 zum ersten Mal schrieb, aber hier im Jahr 2020 unterstützen alle wichtigen modernen Browser Module von Haus aus. Wenn Sie ältere Browser unterstützen müssen, können Sie Bundler wie Webpack und Rollup.js verwenden.
Verwenden Sie das
defer
Attribut für ein klassisches Skript-Tag:Wie beim Modul wird der Code in
my-code.js
parallel zum HTML-Parsing abgerufen und analysiert, jedoch erst ausgeführt, wenn das HTML-Parsing abgeschlossen ist. Funktioniertdefer
jedoch nicht mit Inline-Skriptinhalten , sondern nur mit externen Dateien, auf die über verwiesen wirdsrc
.Ich glaube nicht, dass es das ist, was Sie wollen, aber Sie können das
async
Attribut verwenden, um den Browser anzuweisen, den JavaScript-Code parallel zur HTML-Analyse abzurufen, ihn dann aber so schnell wie möglich auszuführen, auch wenn die HTML-Analyse nicht abgeschlossen ist . Sie können es auf eintype="module"
Tag setzen oder anstelledefer
eines klassischenscript
Tags verwenden.Fügen Sie das
script
Tag am Ende des Dokuments unmittelbar vor dem schließenden</body>
Tag ein:Auf diese Weise sind alle durch den obigen HTML-Code definierten Elemente vorhanden und können verwendet werden, obwohl der Code ausgeführt wird, sobald er angetroffen wird.
Früher verursachte dies bei einigen Browsern eine zusätzliche Verzögerung, da sie den Code erst abrufen konnten, wenn das
script
Tag gefunden wurde. Moderne Browser scannen jedoch voraus und beginnen mit dem Vorabrufen. Dennoch ist dies zu diesem Zeitpunkt die dritte Wahl, beide Module unddefer
sind bessere Optionen.Die Spezifikation hat eine nützliche Diagramm einen rohen zeigt
script
Tag,defer
,async
,type="module"
, undtype="module" async
und den Zeitpunkt , wenn der JavaScript - Code abgerufen und ausgeführt:Hier ist ein Beispiel für das Standardverhalten, ein Raw-
script
Tag:(Siehe meine Antwort hier für Details zu diesem
NodeList
Code.)Wenn Sie das ausführen, sehen Sie "Absatz 1" in Grün, aber "Absatz 2" ist schwarz, da das Skript synchron mit der HTML-Analyse ausgeführt wurde und daher nur den ersten Absatz gefunden hat, nicht den zweiten.
Im Gegensatz dazu ist hier ein
type="module"
Skript:Beachten Sie, wie sie jetzt beide grün sind; Der Code wurde erst ausgeführt, nachdem die HTML-Analyse abgeschlossen war. Dies gilt auch für einen
defer
script
mit externen Inhalten (jedoch nicht für Inline-Inhalte).(Es gab keine Notwendigkeit für die
NodeList
Kontrolle gibt , weil jeder modernen Browser Module bereits UnterstützungforEach
anNodeList
.)In dieser modernen Welt gibt es keinen wirklichen Wert für das
DOMContentLoaded
Ereignis der "Bereit" -Funktion, die PrototypeJS, jQuery, ExtJS, Dojo und die meisten anderen früher bereitstellten (und immer noch bereitstellen). Verwenden Sie einfach Module oderdefer
. Selbst damals gab es nicht viel Grund, sie zu verwenden (und sie wurden oft falsch verwendet, da sie die Seitenpräsentation aufhielten, während die gesamte jQuery-Bibliothek geladen wurde, weil siescript
sich imhead
statt nach dem Dokument befand), was einige Entwickler taten Google hat sich frühzeitig gemeldet. Dies war auch ein Grund für die YUI-Empfehlung , Skripte am Ende desbody
, wieder damals, zu platzieren.quelle
<body onload="doIt()>"
.load
Ereignis tritt sehr spät im Seitenladezyklus auf. Es ist fast nie empfehlenswert, bis dahin mit der Ausführung Ihres JavaScript zu warten. Aber ja, das ist eine Option. Ich habe die Antwort für 2020 übrigens überarbeitet.document.addEventListener('DOMContentLoaded', function(){ //doyour stuff })
Sie können jederzeit Javascript-Code ausführen. AFAIK wird ausgeführt, sobald der Browser das <script> -Tag erreicht, in dem es sich befindet. Sie können jedoch nicht auf Elemente zugreifen, die noch nicht geladen sind.
Wenn Sie also Zugriff auf Elemente benötigen, sollten Sie warten, bis das DOM geladen ist (dies bedeutet nicht, dass die gesamte Seite geladen ist, einschließlich Bilder und Material. Es ist nur die Struktur des Dokuments, die viel früher geladen wurde, sodass Sie normalerweise gewonnen haben keine Verzögerung bemerken), unter Verwendung des
DOMContentLoaded
Ereignisses oder der Funktionen wie$.ready
in jQuery.quelle