Start · Sprachen · JavaScript · Referenz · ShadowRoot.clonable

ShadowRoot.clonable

Eigenschaft

Schreibgeschützter Boolean, der angibt, ob ein Shadow-Root beim Klonen seines Host-Elements (z. B. mit <code>cloneNode()</code>) mitkopiert wird.

seit JavaScript Baseline 2024: Chrome/Edge 124+, Firefox 123+, Saf Kategorie: webapi

Signatur

ShadowRoot.clonable

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: true in Element.prototype.attachShadow(). Standardwert ist false.
  • Deklarativ: über das Boolean-Attribut shadowrootclonable an 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

Typ
boolean
Beschreibung
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);
true true <p>Hallo aus dem Shadow DOM</p>

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);
false null

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);
true

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);
Shadow-Root wird beim Klonen nicht übernommen.

// Wichtig · Fallstricke

  • Nur lesbar: Eine Zuweisung wie shadowRoot.clonable = true wird ignoriert und wirft im Strict Mode einen TypeError. 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 Wert false.
  • Custom Elements: Wenn der Konstruktor eines Custom Elements selbst attachShadow() aufruft, ist clonable: true meist ü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 bei clonable: true ebenfalls kopiert. Über element.shadowRoot kommst 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 undefined und ignorieren die Option. Zum Prüfen eignet sich 'clonable' in ShadowRoot.prototype.