W3docs

HTML <script>-Tag

Das HTML <script>-Tag bettet JavaScript ein oder verknüpft es. Lernen Sie src, async vs. defer, type="module", Platzierung und Attribute mit Beispielen.

Das HTML-Tag <script> deklariert clientseitige Skripte — fast immer JavaScript — in einem HTML-Dokument. Skripte ermöglichen Interaktivität: Formularvalidierung, dynamische Inhaltsaktualisierungen, Bildbearbeitung und die Reaktion auf Benutzerereignisse. Das Tag kann das Skript entweder inline enthalten (zwischen dem öffnenden und schließenden Tag) oder eine externe Datei über das Attribut src laden. Einen umfassenderen Überblick über das Einbinden von Skripten in eine Seite finden Sie unter HTML-Skripte.

Gefahr

Wenn Sie eine externe Datei mit Skripten verknüpfen, betten Sie kein Skript in dasselbe <script>-Tag ein.

Das HTML-Tag <script> kann im Element <head> sowie im Element <body> platziert werden. Skripte, die zuerst ausgeführt werden müssen, werden häufig im <head>-Element mit defer oder am Ende des <body>-Elements platziert. Das <script>-Tag kann in einem HTML-Dokument mehrfach verwendet werden.

Ein script-Tag in einem HTML-Dokument, das auf externes JavaScript verweist

Syntax

Das <script>-Tag kommt immer paarweise vor — ein öffnendes <script> und ein schließendes </script>. Inline-Code steht dazwischen; für eine externe Datei lassen Sie das Tag leer und verweisen src auf die Datei:

<script>
  // inline JavaScript here
  console.log("Hello from inline script");
</script>

<script src="app.js"></script>

Inline-Skript-Beispiel

Zur Auswahl eines HTML-Elements verwendet JavaScript häufig die Methode document.getElementById():

<!DOCTYPE html>
<html>
  <head>
    <title>Title of the document</title>
  </head>
  <body>
    <p id="example"></p>
    <script>
      document.getElementById("example").innerHTML = "My first JavaScript code";
    </script>
  </body>
</html>

Ein externes Skript laden

In echten Projekten speichert man JavaScript fast immer in einer separaten .js-Datei und lädt sie mit src. Dadurch bleibt das HTML übersichtlich, der Browser kann das Skript cachen, und dieselbe Datei kann seitenübergreifend wiederverwendet werden:

<script src="app.js" defer></script>

Einige wichtige Hinweise:

  • Nicht beides mischen. Wenn src vorhanden ist, wird jeglicher Code zwischen den Tags ignoriert. Verwenden Sie entweder Inline-Code oder ein src, aber nicht beides im selben Tag.
  • type="text/javascript" ist überflüssig. JavaScript ist die Standard-Skriptsprache in modernem HTML, daher kann type vollständig weggelassen werden. Setzen Sie type nur, wenn Sie tatsächlich type="module" benötigen (siehe unten).
  • charset hat keine Auswirkung auf externe Skripte heute. Die Zeichenkodierung wird dem HTTP-Content-Type-Header der Datei (und der eigenen Kodierung der Seite) entnommen, daher ist das charset-Attribut bei <script> veraltet — verlassen Sie sich nicht darauf.

async vs. defer

Wenn der Browser beim Parsen von HTML auf ein <script src="..."> trifft, hält er standardmäßig mit dem Parsen an, lädt das Skript herunter, führt es aus und fährt erst dann fort. Das blockiert das Rendering. Die boolean-Attribute async und defer beheben dies — beide laden das Skript parallel herunter ohne das Parsen zu blockieren — unterscheiden sich jedoch darin, wann das Skript ausgeführt wird:

AttributBlockiert das Parsen?Wann es ausgeführt wirdReihenfolge
(keines)JaSofort beim AntreffenIn Dokumentreihenfolge
deferNeinNachdem das HTML vollständig geparst wurde, kurz vor DOMContentLoadedIn Dokumentreihenfolge
asyncNeinSobald der Download abgeschlossen istWer zuerst fertig wird (außerhalb der Reihenfolge)
<!-- Runs after the page is parsed, in order. Safe for code that touches the DOM. -->
<script src="app.js" defer></script>

<!-- Runs as soon as it loads, order not guaranteed. Good for independent scripts
     like analytics that don't depend on other scripts or the parsed DOM. -->
<script src="analytics.js" async></script>

Verwenden Sie defer, wenn Skripte vom DOM oder voneinander abhängig sind (der häufige Fall). Verwenden Sie async für eigenständige, reihenfolgeunabhängige Skripte wie Tracking-Pixel.

Info

async und defer sind boolean-Attribute — ihre bloße Anwesenheit aktiviert sie. Schreiben Sie sie ohne Wert (defer), nicht im alten XHTML-Stil defer="defer". Dasselbe gilt für andere boolean-Attribute wie disabled und checked. Beide Attribute werden bei Inline-Skripten (ohne src) ignoriert.

Skript-Platzierung: <head> vs. Ende von <body>

Der Ort des <script>-Tags ist wichtig, da ein einfaches Skript das Parsen blockiert:

  • <head> mit defer — die moderne Empfehlung. Der Download beginnt früh, während das HTML noch geparst wird, und die Ausführung wartet, bis das DOM bereit ist. Sie erhalten schnelles Laden ohne Blockierung.
  • Ende von <body> — der klassische Ansatz. Wenn der Parser das Skript erreicht, existiert das gesamte DOM bereits, sodass das Skript Elemente sicher abfragen kann. Kein Attribut erforderlich.
<head>
  <script src="app.js" defer></script>
</head>
<body>
  <!-- page content -->
</body>

Vermeiden Sie ein einfaches <script src> (ohne async/defer) im <head>, da es das Rendering der Seite blockiert, bis das Skript heruntergeladen und ausgeführt wurde.

ES-Module mit type="module"

Das Setzen von type="module" verwandelt das Skript in ein ES-Modul. Modul-Skripte verhalten sich anders als klassische Skripte:

  • Sie unterstützen import / export, sodass Sie Code auf mehrere Dateien aufteilen können.
  • Sie sind standardmäßig verzögert — Modul-Skripte warten immer, bis das HTML geparst ist (kein defer erforderlich).
  • Sie laufen immer im Strict Mode und haben ihren eigenen obersten Geltungsbereich (Variablen gelangen nicht in das globale object).
<script type="module" src="main.js"></script>

<script type="module">
  import { greet } from "./greet.js";
  greet("World");
</script>

Um sehr alte Browser zu unterstützen, die Module nicht verstehen, können Sie ein Modul mit einem nomodule-Fallback-Skript kombinieren — moderne Browser führen das Modul aus und ignorieren den Fallback, ältere tun das Gegenteil.

Hinweis zu XHTML und Legacy-Markup

In modernem HTML benötigen Sie kein type-Attribut, und Sie müssen Inline-Skript-Inhalte nicht in einen CDATA-Abschnitt einwickeln. Der Wrapper //<![CDATA[ ... //]]> war nur in XHTML relevant, wo Skriptinhalte als Markup geparst wurden und Sonderzeichen wie < und & maskiert oder geschützt werden mussten. Wenn Sie Standard-HTML schreiben, können Sie dies ignorieren.

Attribute

AttributWertBeschreibung
srcURLURL einer externen Skriptdatei (relativ oder absolut).
async(boolean)Das externe Skript wird parallel abgerufen und sofort nach Verfügbarkeit ausgeführt, ohne das Parsen zu blockieren.
defer(boolean)Das externe Skript wird parallel abgerufen und in der richtigen Reihenfolge nach dem Parsen des HTML ausgeführt.
typeMedientypWird normalerweise weggelassen (JavaScript ist der Standard). Auf module setzen, um ein ES-Modul zu laden.
charsetZeichensatzVeraltet — hat keine Auswirkung; die Kodierung stammt aus dem HTTP-Content-Type der Datei.
crossoriginanonymous | use-credentialsKonfiguriert CORS für die externe Skript-Anfrage.
integrityHashSubresource-Integrity-Hash zur Überprüfung des abgerufenen Skripts.

Das <script>-Tag unterstützt die Globalen Attribute und die Ereignis-Attribute.

Übung

Übung
Welches Attribut ermöglicht es einem externen Skript, ohne Blockierung des Parsens heruntergeladen und in der richtigen Reihenfolge nach dem Parsen des HTML ausgeführt zu werden?
Welches Attribut ermöglicht es einem externen Skript, ohne Blockierung des Parsens heruntergeladen und in der richtigen Reihenfolge nach dem Parsen des HTML ausgeführt zu werden?
Was this page helpful?