Signatur
Beschreibung
Die Eigenschaft innerHTML eines ShadowRoot funktioniert wie Element.innerHTML, bezieht sich aber auf den gesamten Inhalt des Schattenbaums. Beim Lesen bekommst du den serialisierten HTML-Inhalt aller Kindknoten des Shadow Roots, beim Schreiben wird der vorhandene Inhalt komplett entfernt und durch die geparsten Knoten aus dem übergebenen String ersetzt.
Typischerweise nutzt man sie in Web Components, um direkt nach attachShadow() ein Template mit Markup und <style>-Block in den Schattenbaum zu schreiben. Styles darin sind gekapselt, gelten also nur innerhalb der Komponente und werden nicht nach außen weitergegeben.
Wichtig: Das Setzen erzeugt jedes Mal neue Knoten. Event-Listener, Zustände von Formularfeldern und Referenzen auf alte Knoten gehen verloren. Für häufige, kleine Änderungen solltest du deshalb lieber gezielt einzelne Knoten bearbeiten (textContent, replaceChildren(), append()).
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $value | string | Nur beim Setzen: HTML-String, der geparst wird und den gesamten Inhalt des Shadow Roots ersetzt. Ein leerer String entfernt alle Kinder. |
Rückgabewert
ShadowRoot. Ist der Schattenbaum leer, ist es ein leerer String.Beispiele
Web Component mit gekapseltem Markup und Styles
class HalloKarte extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
shadow.innerHTML = `
<style>
.karte { padding: 1rem; border: 1px solid #ccc; border-radius: 8px; }
</style>
<div class="karte"><slot>Standardtext</slot></div>
`;
}
}
customElements.define('hallo-karte', HalloKarte);
document.body.innerHTML = '<hallo-karte>Willkommen!</hallo-karte>';
Inhalt des Shadow Roots auslesen
const host = document.createElement('div');
const root = host.attachShadow({ mode: 'open' });
root.innerHTML = '<p>Hallo <b>Welt</b></p>';
console.log(root.innerHTML);
console.log(host.innerHTML === ''); // Light DOM bleibt leer
Nutzereingaben sicher einfügen
const root = document.createElement('div').attachShadow({ mode: 'open' });
const benutzername = '<img src=x onerror=alert(1)>';
// Unsicher: root.innerHTML = `<p>Hallo ${benutzername}</p>`;
// Sicher: Struktur per innerHTML, Daten per textContent
root.innerHTML = '<p>Hallo <span class="name"></span></p>';
root.querySelector('.name').textContent = benutzername;
console.log(root.innerHTML);
Shadow Root leeren
const root = document.createElement('div').attachShadow({ mode: 'open' });
root.innerHTML = '<ul><li>A</li><li>B</li></ul>';
console.log(root.childNodes.length);
root.innerHTML = '';
console.log(root.childNodes.length);
// Wichtig · Fallstricke
Sicherheit (XSS): Wie bei Element.innerHTML wird der String als HTML geparst. Ungeprüfte Nutzereingaben können Event-Handler-Attribute wie onerror einschleusen. <script>-Elemente, die über innerHTML eingefügt werden, laufen zwar nicht, Inline-Handler dagegen schon. Setze Daten deshalb per textContent oder bereinige sie vorher, etwa mit DOMPurify. Bei aktiven Trusted Types (CSP require-trusted-types-for 'script') muss ein TrustedHTML-Objekt übergeben werden, ein einfacher String löst sonst einen TypeError aus.
- Beim Setzen werden alle bisherigen Knoten samt Event-Listenern ersetzt. Gespeicherte Referenzen zeigen danach auf Knoten, die nicht mehr im Baum hängen.
- Declarative Shadow DOM (
<template shadowrootmode>) wird überinnerHTMLnicht ausgewertet. Dafür gibt essetHTMLUnsafe(). - Bei
mode: 'closed'istelement.shadowRootnull. Den Zugriff hast du dann nur über die Referenz, dieattachShadow()zurückgibt. - Browser-Unterstützung: Chrome/Edge 53+, Firefox 63+, Safari 10+.