Ich habe einige <script>
Elemente, und der Code in einigen von ihnen hängt vom Code in anderen <script>
Elementen ab. Ich habe gesehen, dass das defer
Attribut hier nützlich sein kann, da Codeblöcke bei der Ausführung verschoben werden können.
Um es zu testen, habe ich dies auf Chrome ausgeführt: http://jsfiddle.net/xXZMN/ .
<script defer="defer">alert(2);</script>
<script>alert(1)</script>
<script defer="defer">alert(3);</script>
Es werden jedoch Warnungen ausgegeben 2 - 1 - 3
. Warum alarmiert es nicht 1 - 2 - 3
?
javascript
html
deferred-execution
pimvdb
quelle
quelle
defer
nur bei Angabesrc
. Dies könnte ein Grund sein, warum Ihr Beispiel in den meisten Browsern nicht wie erwartet funktioniert hat.Antworten:
AKTUALISIERT: 19.02.2016
Betrachten Sie diese Antwort als veraltet. Weitere Informationen zu neueren Browserversionen finden Sie in anderen Antworten in diesem Beitrag.
Grundsätzlich weist defer den Browser an, "bis es fertig ist" zu warten, bevor das Javascript in diesem Skriptblock ausgeführt wird. Normalerweise geschieht dies, nachdem das DOM vollständig geladen wurde und document.readyState == 4
Das Attribut "Aufschieben" ist spezifisch für den Internet Explorer. In Internet Explorer 8 ist unter Windows 7 das Ergebnis, das ich auf Ihrer JS Fiddle-Testseite sehe, 1 - 2 - 3.
Die Ergebnisse können von Browser zu Browser variieren.
http://msdn.microsoft.com/en-us/library/ms533719(v=vs.85).aspx
Entgegen der weit verbreiteten Meinung folgt der IE häufiger den Standards, als die Leute es zulassen. Tatsächlich ist das Attribut "Aufschieben" in der DOM Level 1-Spezifikation http://www.w3.org/TR/REC-DOM-Level-1/level definiert -one-html.html
Die Definition des W3C für Aufschub: http://www.w3.org/TR/REC-html40/interact/scripts.html#adef-defer :
"Wenn dieses boolesche Attribut festgelegt ist, gibt es dem Benutzeragenten einen Hinweis darauf, dass das Skript keinen Dokumentinhalt generiert (z. B. kein" document.write "in Javascript), sodass der Benutzeragent das Parsen und Rendern fortsetzen kann."
quelle
Einige Ausschnitte aus der HTML5-Spezifikation: http://w3c.github.io/html/semantics-scripting.html#element-attrdef-script-async
quelle
defer
schlecht implementiert sind . Wenn Sie verwendendefer
, können Sie sich nicht darauf verlassen, dass die Skriptdateien in einigen Browsern in der richtigen Reihenfolge ausgeführt werden.Die wirkliche Antwort lautet: Weil Sie nicht aufschieben können.
Im Konzept unterscheiden sich Defer und Async wie folgt:
Mit async kann das Skript im Hintergrund heruntergeladen werden, ohne es zu blockieren. Sobald der Download abgeschlossen ist, wird das Rendern blockiert und das Skript ausgeführt. Das Rendern wird fortgesetzt, wenn das Skript ausgeführt wurde.
defer macht dasselbe, mit Ausnahme der Ansprüche, die garantieren, dass Skripte in der Reihenfolge ausgeführt werden, in der sie auf der Seite angegeben wurden, und dass sie ausgeführt werden, nachdem das Parsen des Dokuments abgeschlossen ist. Einige Skripte werden möglicherweise heruntergeladen, warten dann auf Skripte, die später heruntergeladen wurden, aber vor ihnen angezeigt wurden.
Leider variiert die Definition von Defer aufgrund eines wirklich standardmäßigen Katzenkampfes von Spezifikation zu Spezifikation, und selbst in den neuesten Spezifikationen bietet dies keine nützliche Garantie. Wie die Antworten hier und in diesem Problem zeigen, implementieren Browser die Verzögerung anders:
defer
Skripte nicht mehr in der richtigen Reihenfolge ausgeführt werden.DOMContentLoaded
Ereignis, bis diedefer
Skripte geladen wurden, andere nicht.defer
auf<script>
Elemente mit Inline - Code und ohnesrc
Attribut, und einige ignorieren.Glücklicherweise gibt die Spezifikation zumindest an, dass asynchrone Überschreibungen verzögert werden. So können Sie alle Skripte als asynchron behandeln und eine breite Palette an Browserunterstützung erhalten, wie folgt:
98% der weltweit verwendeten Browser und 99% in den USA vermeiden mit diesem Ansatz das Blockieren.
(Wenn Sie warten müssen, bis das Dokument analysiert wurde, hören Sie sich das Ereignis an
DOMContentLoaded
oder verwenden Sie die praktische.ready()
Funktion von jQuery . Sie sollten dies trotzdem tun, um auf Browser zurückzugreifen, die überhaupt nicht implementiert sinddefer
.)quelle
defer
Attribut seit Version 15 unterstützt , die am 2. Juni 2013 veröffentlicht wurde .defer
kann nur in<script>
Tags für die Aufnahme externer Skripte verwendet werden. Daher wird empfohlen,<script>
in den<head>
-tags im -section zu verwenden.quelle
Das Attribut as defer funktioniert nur mit dem Skript-Tag src. Es wurde eine Möglichkeit gefunden, die Verzögerung für Inline-Skripte nachzuahmen. Verwenden Sie das DOMContentLoaded-Ereignis.
Dies liegt daran, dass das Ereignis DOMContentLoaded ausgelöst wird, nachdem zurückgestellte zugeordnete Skripte vollständig geladen wurden.
quelle
Das Attribut defer gilt nur für externe Skripte (sollte nur verwendet werden, wenn das Attribut src vorhanden ist).
quelle
Es sollte auch beachtet werden, dass es in IE <= 9 Probleme geben kann, wenn
script defer
in bestimmten Situationen verwendet wird. Mehr dazu: https://github.com/h5bp/lazyweb-requests/issues/42quelle
Schauen Sie sich diesen hervorragenden Artikel an. Tauchen Sie tief in das trübe Wasser des Ladens von Skripten ein, das der Google-Entwickler Jake Archibald 2013 geschrieben hat.
Zitieren des relevanten Abschnitts aus diesem Artikel:
(Ich werde hinzufügen, dass frühe Versionen von Firefox DOMContentLoaded auslösen, bevor die
defer
Skripte laut diesem Kommentar ausgeführt werden .)Moderne Browser scheinen dies
async
ordnungsgemäß zu unterstützen , aber Sie müssen mit Skripten einverstanden sein, die nicht in der richtigen Reihenfolge und möglicherweise vor DOMContentLoaded ausgeführt werden.quelle
Dieses boolesche Attribut gibt einem Browser an, dass das Skript ausgeführt werden soll, nachdem das Dokument analysiert wurde. Da diese Funktion noch nicht von allen anderen gängigen Browsern implementiert wurde, sollten Autoren nicht davon ausgehen, dass die Ausführung des Skripts tatsächlich verzögert wird. Rufen Sie niemals document.write () aus einem verzögerten Skript auf (seit Gecko 1.9.2 wird das Dokument dadurch weggeblasen). Das Attribut defer sollte nicht für Skripte verwendet werden, die das Attribut src nicht haben. Seit Gecko 1.9.2 wird das Attribut defer in Skripten ignoriert, die das Attribut src nicht haben. In Gecko 1.9.1 werden jedoch auch Inline-Skripte zurückgestellt, wenn das Attribut defer festgelegt ist.
Aufschieben funktioniert mit Chrom, Firefox, dh> 7 und Safari
Ref: https://developer.mozilla.org/en-US/docs/HTML/Element/script
quelle
Das Defer-Attribut ist ein boolesches Attribut.
Wenn vorhanden, wird angegeben, dass das Skript ausgeführt wird, wenn die Analyse der Seite abgeschlossen ist.
Hinweis: Das Attribut defer gilt nur für externe Skripte (sollte nur verwendet werden, wenn das Attribut src vorhanden ist).
Hinweis: Es gibt verschiedene Möglichkeiten, wie ein externes Skript ausgeführt werden kann:
Wenn Async vorhanden ist: Das Skript wird asynchron mit dem Rest der Seite ausgeführt (das Skript wird ausgeführt, während die Seite das Parsen fortsetzt). Wenn Async nicht vorhanden ist und Defer vorhanden ist: Das Skript wird ausgeführt, wenn die Seite das Parsen beendet hat. If Es ist weder asynchron noch verzögert vorhanden: Das Skript wird sofort abgerufen und ausgeführt, bevor der Browser die Seite weiter analysiert
quelle