Laden als Datei oder direkt einsetzen
Im script-Element können Script-Anweisungen direkt eingesetzt werden, aber script kann auch eine externe Script-Datei mittels scr-Attribut laden. Ohne weitere Vorsorge führt der Browser führt das Script sofort an Ort und Stelle aus.
Heute unterstützen die modernen Browser die Attribute async und defer im öffnenden script-Tag, die den Ladevorgang besser steuern. async wird vorzugsweise für externe Scripte eingesetzt, defer, wenn sichergestellt ist, dass Anweisungen das HTML-Markup nicht ändern.
<head> <link rel="stylesheet" href="style.css" media="all"> <script src="script.js" async></script> ▲ │ └──── Externe Scriptdatei einbinden </head>
Das script-Tag muss immer durch </script> geschlossen werden.
┌─── Anfang des Scripts │ ▼ <script> const h = document.getElementById('main'); h.innerHTML = '<h1>Scripte Einbinden</h1>'; </script> ▲ │ └─── Ende des Scriptbereichs
Javascript ändert Inhalte, CSS-Stile oder HTML-Elemente und kann erst erst fehlerfrei ausgeführt werden, wenn das DOM, CSS-Dateien, globale CSS-Stile und der Inhalt bereits geladen sind. Wenn das Javascript im head der HTML-Seite geladen wird, stellt der Browser alle weiteren Elemente zurück, bis das Script geladen und interpretiert ist. Das kann zu einem sichtbaren Aussetzer beim Laden der Seite führen. Wenn das Script schon in HTML head geladen werden muss, dann besser nach allen CSS-Dateien.
Seite vollständig geladen
Wenn das Script im head-Element der Webseite ausgeführt wird, braucht es einen Mechanismus, der feststellt, ob die Seite vollständig geladen ist – einen Event-Handler). Es mag zwar übersichtlicher sein, das script-Element in die head-Region der Webseite zu setzen – aber bei längeren Scripten ist es effizienter, das Script erst am Ende der Seite zu laden.
script-Element am Ende der HTML-Datei
<html> <head> … </head> <body> … <script src="script.js"></script> <script> console.log ("Das Ende naht"); </script> </body> </html>
Auch wenn das Script am Ende der Seite geladen wird, kommt es zu einem Aussetzer, den der Benutzer aber kaum wahrnehmen wird, da die Seite jetzt ins Browserfenster geladen und formatiert ist.
script defer / async
Das Laden eines Scripts verzögert den Aufbau der Seite. Wenn das Script nicht benötigt wird, um die Seite aufzubauen, kann das Script auch am Ende des HTML-Dokuments geladen werden.
- Wenn weder async noch defer notiert sind, beginnt die Ausführung sofort und noch bevor der Browser die Seite parst.
- defer im script-Tag weist den Browser an, das Script erst auszuführen, wenn alle Elemente der Seite fertig geparst sind. In der Praxis ist es allerdings nicht einfach, diesen Zeitpunkt im Script abzusehen. defer reicht z.B. nicht unbedingt, um sicherzustellen, dass alle Elemente geladen sind, auf die das Script zugreifen soll.
- Wenn async="async" im script-Tag notiert ist, wird das Script asynchron geladen, während der Browser den der Rest der Seite parst.
Auch mit defer und async zählen das Laden und Initialisieren des Scripts zur Ladezeit der Seite.
Einfaches Javascript einbinden
<p><button id="halloScript">Sag Hallo</button></p> … <script> const halloScript = document.getElementById("halloScript"); halloScript.onclick = function () { console.log ("Hallo Script"); } </script>
Der button-Element ist durch ein id-Attribut halloScript eindeutig identifiziert. Das Script liegt im HTML-Quelltext hinter dem button-Element, so dass kein besonderer Mechanismus feststellen, ob das DOM bereits geladen ist. Die Platzierung im HTML-Quelltext hält das Script einfach, taugt aber nur für derart einfache Beispiele.
Attribute für script
- async HTML5
- Das Script wird asynchron – d.h. parallel zu anderen Resourcen geladen, um die Ladezeit des Scripts zu verkürzen. Nur bei externen Script-Dateien.
- charset
- legt den Zeichensatz fest, der für das Script benutzt wird.
- defer
- informiert den Server, dass dieses Script den Inhalt der Webseite nicht schon beim Laden ändert. Der Browser kann das Laden und die Ausführung des Scripts verzögern, bis das HTML und die Inhalte geladen sind. Die Seite kann schneller aufgebaut werden.
- src
- die URL der Datei, die das Script enthält. Eine Auslagerung des Scriptcodes in eine separate Datei ist sinnvoll, wenn das Script auf mehreren Seiten einer Website genutzt wird. Der Browser lädt und führt das Script als separate Datei aus.
Wenn das src-Attribut vorhanden ist, muss das script-Element leer bleiben – dann dürfen keine script-Anweisungen innerhalb des script-Elements stehen. - type ES06
- definiert die benutzte Scriptsprache. Die beiden gebräuchlichsten Werte sind text/javascript und text/vbscript. text/javascript ist die Vorgabe und muss nicht notiert werden.
Seit ES06 gibt es den Wert module für das type-Attribut und ermöglicht den Import und Export von Modulen.
Metadaten mit LD JSON
Im type-Attribut des script-Tags darf alles Mögliche stehen – wenn es nicht text/javascript ist, wird es vom Browser ignoriert.
Es gibt noch eine dritte Variante für das Script-Tag: type = "application/ld+json".
JSON LD enthält keinen Script-Code, sondern enthält die Metadaten der Seite und trennt sie vom Inhalt. JSON LD ersetzt die zahllosen meta-Tags und Attribute, die bei Microformats, RDF und Microdata den HTML-Quelltext fluten.
<script type="application/ld+json"> { "@context": "http://schema.org", "@type": "WebPage", "headline": "Javascript in HTML einbinden", "datePublished": "2008-12-12", "dateModified": "2021-11-24", "lastReviewed": "2021-02-12", "description": "Das script-Element lädt Javascript via src-Attribut …", "primaryImageOfPage" : [ "https://www.mediaevent.de/html/svg/script.png" ] } </script>
language-Attribut und falscher Mime-Type
Früher setzen Entwickler ein language-Attribut in das script-Tag, um dem Broswer die verwendete Javascript-Version mitzuteilen. In der Praxis können Browser aber mit dem language-Attribut nichts anfangen. Ob der Browser tatsächlich in der Lage ist, das Script auszuführen, wird im Script durch einen Mechanismus geprüft, der „Object-Detection“ – Objekterkennung – genannt wird. Das language-Attribut war schon in XHTML unerwünscht, da es unzuverläßig ist.
Und noch so ein Habitus: type="text/javascript" ist ebenso nutzlos. Das W3C simulierte damit einen Javascript-Mime-Typ, den es noch nicht gab und den kein Browser erkennt. Der Mime-Typ für Javascript kam erst viel später auf die Welt und lautet application/javascript.