Start · Sprachen · JavaScript · Referenz · ShadowRoot.host

ShadowRoot.host

Eigenschaft

Die schreibgeschützte Eigenschaft <code>ShadowRoot.host</code> liefert das Element, an das der Shadow Root angehängt ist (das sogenannte Shadow-Host-Element).

seit JavaScript Baseline: alle modernen Browser (seit 2020) Kategorie: webapi

Signatur

get ShadowRoot.host

Beschreibung

Jeder ShadowRoot gehört zu genau einem Element, dem Shadow Host. Die Eigenschaft host gibt eine Referenz auf dieses Element zurück. Das ist die Gegenrichtung zu Element.shadowRoot: Vom Host kommt man über element.shadowRoot in den Schatten-Baum, und von innen führt shadowRoot.host wieder heraus zum Host.

Gebraucht wird das vor allem in Web Components: Code, der im Schatten-Baum läuft, etwa ein Event-Handler auf einem inneren Button, kann über node.getRootNode().host die zugehörige Komponente finden. Dort liest er dann Attribute, setzt Zustände oder löst eigene Events am Host aus. Auch Bibliotheken nutzen host, um beim Durchlaufen des DOM über Shadow-Grenzen hinweg nach oben zu gehen.

Die Eigenschaft ist schreibgeschützt. Ein Shadow Root lässt sich nicht nachträglich an ein anderes Element hängen, und zu jedem Host gehört höchstens ein Shadow Root. Mit mode: "closed" gibt element.shadowRoot von außen null zurück. Wer eine Referenz auf den Root hat, erreicht über host aber trotzdem das Host-Element.

Rückgabewert

Typ
Element
Beschreibung
Das Element, an das der ShadowRoot angehängt ist. Es ist immer gesetzt und nie null.

Beispiele

Host aus einem Shadow Root ermitteln

const div = document.createElement('div');
div.id = 'widget';
const root = div.attachShadow({ mode: 'open' });

console.log(root.host === div);
console.log(root.host.id);
console.log(div.shadowRoot === root);
true widget true

Aus einem inneren Event-Handler die Komponente erreichen

class LikeButton extends HTMLElement {
  constructor() {
    super();
    const root = this.attachShadow({ mode: 'open' });
    root.innerHTML = '<button type="button">Gefällt mir</button>';
    root.querySelector('button').addEventListener('click', (event) => {
      // Vom inneren Button zum Host (der Komponente) gelangen
      const host = event.currentTarget.getRootNode().host;
      const count = Number(host.dataset.count ?? 0) + 1;
      host.dataset.count = count;
      host.dispatchEvent(new CustomEvent('like', { detail: { count }, bubbles: true, composed: true }));
    });
  }
}
customElements.define('like-button', LikeButton);

const btn = document.createElement('like-button');
document.body.append(btn);
btn.addEventListener('like', (e) => console.log('Likes:', e.detail.count));
btn.shadowRoot.querySelector('button').click();
Likes: 1

DOM über Shadow-Grenzen hinweg nach oben durchlaufen

// Liefert den nächsten Vorfahren, der auf den Selektor passt, auch über Shadow Roots hinweg
const closestComposed = (node, selector) => {
  let current = node;
  while (current) {
    if (current instanceof Element && current.matches(selector)) return current;
    current = current.parentNode instanceof ShadowRoot
      ? current.parentNode.host
      : current.parentNode;
  }
  return null;
};

const section = document.createElement('section');
section.className = 'card';
const host = document.createElement('div');
section.append(host);
const inner = document.createElement('span');
host.attachShadow({ mode: 'open' }).append(inner);

console.log(inner.closest('.card'));
console.log(closestComposed(inner, '.card') === section);
null true

// Wichtig · Fallstricke

  • Schreibgeschützt: Eine Zuweisung an host wird im nicht-strikten Modus stillschweigend ignoriert und löst im Strict Mode einen TypeError aus.
  • Nur auf ShadowRoot: getRootNode() gibt für normale Knoten das Document zurück, und das hat keine Eigenschaft host (Ergebnis: undefined). Vor dem Zugriff mit root instanceof ShadowRoot prüfen.
  • Geschlossene Shadow Roots: Mit mode: "closed" kann man host nur lesen, wenn man eine Referenz auf den Root hat, etwa über getRootNode() von innen. Die Kapselung ist damit kein Sicherheitsmechanismus.
  • Kein Umhängen: Der Host bleibt für die ganze Lebensdauer des Shadow Roots gleich. Ein Element kann nur einen Shadow Root haben, ein zweiter Aufruf von attachShadow() löst eine NotSupportedError-DOMException aus.
  • Kompatibilität: Wird in Chrome/Edge 53+, Firefox 63+ und Safari 10+ unterstützt. In sehr alten Browsern nur über Polyfills (Shadow DOM v0 ist veraltet).