HTML

Knowledge Base

HTML

Script-Element

Das <script></script> Element kann zu verwendet werden, um

  • Skript Quellcode (i. d. R. JavaScript) innerhalb (inline) des Dokuments zu definieren
  • eine externe Datei mit Script Quellcode (i. d. R. JavaScript) an einer bestimmten Stelle im Dokument zu laden

Das Script-Element kann innerhalb des <head></head> oder des <body></body> Elements eingesetzt werden. In HTML5 muss es zu jedem Starttag auch immer ein Endtag geben (es handelt sich hier um ein "Raw Text Element" und nicht um ein "Void Element" - siehe auch W3C - HTML Syntax).

Beispiel für Einfügen von JavaScript Quellcode direkt innerhalb des Dokuments (in HTML5 sind keine weiteren Attribute erforderlich, weil als Standardtyp type="text/javascript" definiert ist):

<script>
    document.write("Hello World");
</script>

Beispiel für das Laden einer JavaScript Datei:

<script src="JS/jquery.js"></script>

Der Browser lädt zunächst das HTML-Dokument und arbeitet dieses von oben nach unten ab. Trifft der Browser dabei auf ein Script-Element wird dieses unmittelbar ausgeführt (bei einer externen Datei wird diese dazu erstmal geladen) und erst dann verfolgt der Browser den Rest des Dokuments - das entspricht einer (synchronen) Abarbeitung von HTML-Dokument von oben nach unten.

Werden durch das ausgeführte SkriptElemente des HTML Dokuments verändert, müssen diese Elemente bereits vom Browser verarbeitet worden sein, d. h. das Script muss zu einem späteren Zeitpunkt ausgeführt werden - entweder dadurch, dass es im Dokument unterhalb platziert wird oder in dem das Script auf bestimmte Ereignisse (z. B. vollständiges Laden des Dokuments) wartet (durch Ereignis-Listener) und erst dann (in dem Ereignis-Handler) die gewünschten Elemente bearbeitet.


Attribute von <script>:

  • type="<MIME Typ>": Gibt die Sprache oder das Format des Inhalts an (entweder des inline Scripts oder des Inhalts der externen Datei an. In HTML5 (Neu in HTML5) verwendet als Standard type="text/javascript", d. h. wird JavaScript verwendet kann, muss dieses Attribut nicht verwendet werden.
  • src="<Name der Datei>": Gibt den Namen (und Pfad) der zu ladenden externen Datei an. In diesem Fall kann (und sollte) kein Skript Quellcode zwischen <script></script> vorhanden sein, da es von den meisten Browsern einfach ignoriert und nicht ausgeführt wird (z. B. Firefox, Chrome, Internet Explorer). Man kann mit einem <script> Element entweder Skript Quellcode innerhalb des HTML Dokuments (inline) oder in einem externen Dokument definieren (aber nicht beides).
  • charset="<Charset Type>": Gibt die Codierung der externen Skript Datei an, wenn diese von der Codierung  und darf auch nur in Kombination mit src verwendet werden (also nicht beim Skript innerhalb (inline) des Dokuments.
  • async (Neu in HTML5): Gibt an, dass das Skript (der externen Datei) parallel zum Parsing / Rendern des HTML Dokuments geladen werden "darf" (im Gegensatz zum synchronen Laden, bei dem das Parsen des HTML Dokuments unterbrochen wird, bis das Script geladen wird). Ist das Skript aber geladen, wird es auch sofort ausgeführt (und das Parsen des HTML Dokuments wird während der Ausführung des Skripts ebenfalls unterbrochen). Async darf nur in Kombination mit src verwendet werden.
  • defer: Wie bei async wird das Skript parallel zum Parsen geladen, aber erst ausgeführt, wenn das Parsen abgeschlossen ist. Defer darf nur in Kombination mit src verwendet werden.

 Defer wird tendenziell mehr von älteren Browsern unterstützt als async. Sind beide Attribute vorhanden hat async Vorrang vor defer (defer ist damit dann der Fallback, falls der Browser kein async unterstützt).

Vorsicht: Async / Defer Skripte können zu unterschiedlichsten Zeiten ausgeführt werden und auch die Reihenfolge (bei mehreren Skripten) ist nicht immer sicher vorhersagbar. Zwangsläufig muss das enthaltene Skript also unabhängig von anderen Skripten funktionieren und zu jeder Zeit ausführbar sein. Skript, welches Elemente des HTML Dokuments verarbeitet oder verändert, sollte entsprechend erst dann ausgeführt werden, wenn das Dokument bereit ist (z. B. in jQuery mit $(document).ready(fn), welches den Quellcode der Funktion "fn" erst ausführt, wenn das Dokument "ready" ist).


Positionierung von Skripten / Verwendung von defer / async:

Im Web (wie auch hier ;-)) finden sich verschiedene Überlegungen, wo und wie eine Script-Datei geladen werden soll. Insbesondere wird dies auch angeheizt durch zahlreiche "Belohnungen" (in Form von höheren Positionen im Suchergebnis) einer großen Suchmaschine, im Falle dass die Seite besonders "schnell" lädt - d. h. primär geht es um die Ladezeit bzw. auch ab welchem Zeitpunkt, die Seite für den Benutzer zur Verfügung steht.

Ursprünglich wurden Skripte synchron im Header geladen. Mit dieser Vorgehensweise wird vgl. früh nach dem Laden des HTML Dokuments das Parsen unterbrochen (bis das Skript geladen und ausgeführt wird). Da zu diesem Zeitpunkt das HTML Dokument (und dessen Elemente nicht zur Verfügung stehen) muss zwangsläufig zunächst auf das Ende des Dokuments gewartet werden (z. B. mit jQuery $(document).ready(fn)).

Andere Überlegungen sind, die Skripte erst am Ende des Dokuments - kurz vor dem schließenden </body> hinzuzufügen. Dies hat die Vorteile, dass

  • alle Elemente der Seite bereits geparst wurden (und damit unmittelbar für "Veränderungen" zur Verfügung stehen)
  • die Seite bereits am Bildschirm gerendert wurde (und der Benutzer etwas sehen kann)

Allerdings gibt es mit diesem Ansatz auch Nachteile, da

  • die (evtl. größeren) Skript-Dateien überhaupt erst nach dem Parsen der Seite geladen und erst dann ausgeführt wurden, d. h. die Seite ist zwar sichtbar, aber evtl. viel später erst funktional bereit (was für den Benutzer evtl. sogar irritierender ist, wenn z. B. ein JavaScript Menü oder der Klick auf ein Button nicht funktioniert).
  • die Gesamtladezeit nicht geringer ist, als im Vergleich zum synchronen Laden

State-Of-The-Art Überlegungen sind es die Scripte parallel zum Parsen der Seite zu laden (mit den Attributen async oder defer) und auch unmittelbar nach dem Laden auszuführen (async) bzw. auf die Bereitsstellung des Dokuments warten (defer oder z. B. mit jQuery $(document).ready(fn)). In diesem Fall müssen die notwendigen Script Elemente innerhalb des Headers stehen (damit das Laden der Dateien bereits parallel zum Parsen des HTML Dokuments starten kann).

Falls synchrones Skript wirklich notwendig ist (z. B. falls das Skript direkt Ausgaben während des Parsens erzeugt (mit "document.write()") oder jüngst hinzugefügte HTML Elemente verändert werden sollen (z. B. ältere Drittkomponenten-Bibliotheken genutzt, z. B. um HTML Elemente unmittelbar nach dem Parsen um Funktionen zu ergänzen), sollte dieses innerhalb (inline) des HTML Dokuments verwendet werden (und nicht unbedingt in einer externen Datei ausgelagert werden).