Signatur
Beschreibung
Die schreibgeschützte Eigenschaft clonable des ShadowRoot-Interfaces gibt true zurück, wenn das Shadow-Root klonbar ist, sonst false. Ist sie true, erhält eine Kopie des Host-Elements, die mit Node.prototype.cloneNode() oder Document.prototype.importNode() erzeugt wird, ebenfalls ein eigenes Shadow-Root mit einer Kopie des Shadow-Inhalts.
Den Wert legst du nur beim Erzeugen des Shadow-Roots fest und kannst ihn danach nicht mehr ändern:
- Imperativ: über die Option
clonable: trueinElement.prototype.attachShadow(). Standardwert istfalse. - Deklarativ: über das Boolean-Attribut
shadowrootclonablean einem<template shadowrootmode="open">-Element.
Sinnvoll ist die Eigenschaft bei Komponenten ohne eigene Custom-Element-Klasse. Das betrifft etwa per deklarativem Shadow DOM serverseitig gerenderte Bausteine oder einfache Elemente wie <div> mit Shadow-Root, die in Listen oder Vorlagen vervielfältigt werden sollen. Das geklonte Shadow-Root übernimmt mode, delegatesFocus, slotAssignment, serializable und clonable vom Original.
Rückgabewert
true, wenn das Shadow-Root beim Klonen des Hosts mitkopiert wird, sonst false (Standardwert).Beispiele
Klonbares Shadow-Root mit attachShadow() anlegen
const host = document.createElement('div');
const shadow = host.attachShadow({ mode: 'open', clonable: true });
shadow.innerHTML = '<p>Hallo aus dem Shadow DOM</p>';
console.log(shadow.clonable);
// Beim Klonen wird das Shadow-Root mitkopiert
const copy = host.cloneNode(true);
console.log(copy.shadowRoot !== null);
console.log(copy.shadowRoot.innerHTML);
Standardverhalten: Shadow-Root wird nicht geklont
const host = document.createElement('div');
const shadow = host.attachShadow({ mode: 'open' });
shadow.textContent = 'Inhalt';
console.log(shadow.clonable);
const copy = host.cloneNode(true);
console.log(copy.shadowRoot);
Deklaratives Shadow DOM mit shadowrootclonable
// HTML:
// <div id="karte">
// <template shadowrootmode="open" shadowrootclonable>
// <style>p { color: teal; }</style>
// <p><slot></slot></p>
// </template>
// Produktname
// </div>
const karte = document.getElementById('karte');
console.log(karte.shadowRoot.clonable);
// Karte mehrfach vervielfältigen, der Shadow-Inhalt wird mitkopiert
const liste = document.createElement('section');
for (const name of ['Tisch', 'Stuhl']) {
const kopie = karte.cloneNode(true);
kopie.removeAttribute('id');
kopie.lastChild.textContent = name;
liste.append(kopie);
}
document.body.append(liste);
Klonbarkeit vor dem Kopieren prüfen
const cloneWithShadow = (el) => {
const root = el.shadowRoot;
if (root && !root.clonable) {
console.warn('Shadow-Root wird beim Klonen nicht übernommen.');
}
return el.cloneNode(true);
};
const host = document.createElement('div');
host.attachShadow({ mode: 'open' });
cloneWithShadow(host);
// Wichtig · Fallstricke
- Nur lesbar: Eine Zuweisung wie
shadowRoot.clonable = truewird ignoriert und wirft im Strict Mode einenTypeError. Der Wert lässt sich ausschließlich beim Erzeugen festlegen. - Deklaratives Shadow DOM: In frühen Implementierungen waren deklarative Shadow-Roots automatisch klonbar. Heute brauchst du dafür ausdrücklich das Attribut
shadowrootclonable, sonst ist der Wertfalse. - Custom Elements: Wenn der Konstruktor eines Custom Elements selbst
attachShadow()aufruft, istclonable: truemeist überflüssig, denn der Konstruktor erzeugt das Shadow-Root beim Klonen ohnehin neu. Beides zu kombinieren kann zu doppelten oder widersprüchlichen Shadow-Roots führen, darum solltest du dich für einen der beiden Wege entscheiden. - Geschlossene Shadow-Roots (
mode: 'closed') werden beiclonable: trueebenfalls kopiert. Überelement.shadowRootkommst du aber auch beim Klon nicht an sie heran. - Nur Kopie des Inhalts: Event-Listener und JavaScript-Zustand im Shadow-Baum werden nicht mitkopiert, wie bei
cloneNode()üblich. - Kompatibilität: Unterstützt ab Chrome/Edge 124, Firefox 123 und Safari 17.4. Ältere Browser liefern
undefinedund ignorieren die Option. Zum Prüfen eignet sich'clonable' in ShadowRoot.prototype.