Signatur
Beschreibung
HTMLScriptElement ist die DOM-Schnittstelle für <script>-Elemente. Sie erbt von HTMLElement und ergänzt Eigenschaften, die den HTML-Attributen des Elements entsprechen: src, type, async, defer, noModule, crossOrigin, integrity, referrerPolicy, fetchPriority, blocking und text.
Gebraucht wird die Schnittstelle vor allem zum dynamischen Nachladen von Skripten, etwa für Analyse-Tools, Drittanbieter-Widgets, Polyfills, die nur bei Bedarf geladen werden, oder JSONP-Altlösungen. Man erzeugt mit document.createElement('script') ein Element, setzt src und hängt es in das Dokument ein. Das Skript wird geladen und ausgeführt, sobald das Element im DOM ist. Die Events load und error melden, ob das geklappt hat.
Wichtig: Dynamisch erzeugte Skripte sind standardmäßig async = true. Sie blockieren also nicht und werden in der Reihenfolge ausgeführt, in der sie fertig geladen sind. Brauchen Sie eine feste Reihenfolge, setzen Sie script.async = false. Die statische Methode HTMLScriptElement.supports(type) prüft, ob der Browser einen Skripttyp unterstützt, z. B. "module", "importmap" oder "speculationrules".
Über document.currentScript bekommt ein klassisches Skript während seiner Ausführung Zugriff auf sein eigenes HTMLScriptElement. So kann es z. B. data-*-Attribute als Konfiguration auslesen.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $src | string | "" | URL des externen Skripts. Das Attribut src spiegelt sich hier als absolute URL. |
| $type | string | "" | MIME-Typ oder Skripttyp, z. B. "module", "importmap" oder "application/json" (ein Datenblock, der nicht ausgeführt wird). |
| $async | boolean | true bei dynamischen Skripten, sonst false | Wenn true, wird das Skript parallel geladen und sofort ausgeführt, sobald es verfügbar ist. |
| $defer | boolean | false | Führt ein klassisches Parser-Skript erst aus, wenn das Dokument fertig geparst ist. Bei dynamisch eingefügten Skripten hat defer keine Wirkung. |
| $noModule | boolean | false | Wenn true, führen Browser mit ES-Modul-Unterstützung das Skript nicht aus. Dient als Fallback für ältere Browser. |
| $crossOrigin | string | null | null | CORS-Modus: "anonymous" oder "use-credentials". Nötig für aussagekräftige Fehlermeldungen und für integrity bei fremden Ursprüngen. |
| $integrity | string | "" | Subresource-Integrity-Hash, z. B. "sha384-…". Das Skript wird nur ausgeführt, wenn der Hash stimmt. |
| $referrerPolicy | string | "" | Referrer-Richtlinie für den Abruf des Skripts, z. B. "no-referrer". |
| $fetchPriority | "high" | "low" | "auto" | "auto" | Gibt dem Browser einen Hinweis, mit welcher Priorität er das Skript laden soll. |
| $text | string | "" | Inline-Quelltext des Skripts, entspricht textContent. |
| $HTMLScriptElement.supports(type) | static (type: string) => boolean | Statische Methode, die prüft, ob der Browser den Skripttyp type unterstützt. |
Rückgabewert
document.createElement('script'), durch new DOMParser() oder durch Abfrage vorhandener Elemente (z. B. document.querySelector('script')). Einen öffentlichen Konstruktor gibt es nicht.Beispiele
Skript dynamisch nachladen (mit Promise)
const loadScript = (src, { integrity, crossOrigin = 'anonymous' } = {}) =>
new Promise((resolve, reject) => {
const script = document.createElement('script');
script.src = src;
script.crossOrigin = crossOrigin;
if (integrity) script.integrity = integrity;
script.addEventListener('load', () => resolve(script));
script.addEventListener('error', () => reject(new Error(`Laden fehlgeschlagen: ${src}`)));
document.head.append(script);
});
try {
await loadScript('https://cdn.jsdelivr.net/npm/dayjs@1/dayjs.min.js');
console.log('dayjs geladen:', typeof window.dayjs);
} catch (err) {
console.error(err.message);
}
Mehrere Skripte in fester Reihenfolge ausführen
const urls = ['/js/vendor.js', '/js/plugin.js', '/js/app.js'];
for (const url of urls) {
const script = document.createElement('script');
script.src = url;
script.async = false; // Ausführungsreihenfolge = Einfügereihenfolge
document.body.append(script);
}
Konfiguration über document.currentScript lesen
// <script src="/widget.js" data-theme="dark" data-lang="de"></script>
const self = document.currentScript;
const { theme = 'light', lang = 'en' } = self?.dataset ?? {};
console.log(`Widget: Theme=${theme}, Sprache=${lang}`);
Unterstützte Skripttypen prüfen und JSON-Datenblock lesen
if (typeof HTMLScriptElement.supports === 'function') {
console.log('importmap:', HTMLScriptElement.supports('importmap'));
console.log('speculationrules:', HTMLScriptElement.supports('speculationrules'));
}
// <script type="application/json" id="init-data">{"userId": 42}</script>
const dataEl = document.getElementById('init-data');
const data = JSON.parse(dataEl?.text ?? '{}');
console.log(data.userId);
// Wichtig · Fallstricke
- innerHTML führt keine Skripte aus: Ein
<script>, das Sie überinnerHTMLeinfügen, wird nicht ausgeführt. Es muss percreateElementerzeugt oder mitdocument.createRange().createContextualFragment()geparst werden. Letzteres führt Skripte aus und ist daher ein XSS-Risiko. - Sicherheit: Laden Sie nie Skript-URLs oder Skript-Text, der aus Benutzereingaben stammt. Setzen Sie
src,textodertextContentmit fremden Daten, führt das direkt zu XSS. Mit einer Content Security Policy (script-src, Nonces,strict-dynamic) und Trusted Types (TrustedScriptURL) können Sie das absichern. Setzen Sie für CDN-Skripteintegrityzusammen mitcrossOrigin. - Einmalige Ausführung: Ein Skriptelement wird nur einmal ausgeführt. Ändern Sie danach
srcoder fügen Sie das Element erneut ein, lädt der Browser nichts nach. Erzeugen Sie dafür ein neues Element. deferwirkt nur bei Skripten, die der Parser mitsrceinliest, nicht bei dynamisch eingefügten. Modul-Skripte (type="module") verhalten sich automatisch wiedefer.- Bei Skripten von fremden Ursprüngen ohne
crossOriginliefertwindow.onerrornur „Script error.“ ohne Details. document.currentScriptist in ES-Modulennull. Verwenden Sie dortimport.meta.url.- Kompatibilität: Die Kernfunktionen laufen in allen Browsern.
HTMLScriptElement.supports(),fetchPriorityundblockingsind neuer und sollten vor der Nutzung per Feature-Erkennung geprüft werden.