Start · Sprachen · JavaScript · Referenz · Node.getRootNode()

Node.getRootNode()

Methode

Gibt die Wurzel des Baums zurück, in dem sich ein Knoten befindet, also <code>Document</code>, <code>ShadowRoot</code> oder den obersten Knoten eines losgelösten Teilbaums.

seit JavaScript Baseline: alle modernen Browser (Chrome 54, Firefo Kategorie: webapi

Signatur

Node.prototype.getRootNode(options)

Beschreibung

getRootNode() läuft vom aktuellen Knoten über die Elternkette nach oben und gibt den obersten Knoten zurück. Bei einem Element, das normal im Dokument hängt, ist das das Document. Liegt das Element in einem Shadow DOM, ist es standardmäßig die zugehörige ShadowRoot. Hängt der Knoten nirgends ein (zum Beispiel ein mit document.createElement() erzeugtes Element, das noch nicht eingefügt wurde), ist es der oberste Vorfahre des losgelösten Teilbaums oder der Knoten selbst.

Die Methode ist vor allem für Web Components nützlich. Eine Komponente kann damit herausfinden, ob sie im Shadow DOM einer anderen Komponente liegt, und dann in genau diesem Baum Elemente suchen (root.getElementById(), root.querySelector()), Styles einhängen oder das aktive Element abfragen (root.activeElement). Das funktioniert unabhängig davon, ob die Komponente im Dokument oder in einem Shadow Root steckt.

Mit der Option { composed: true } überspringt die Methode Shadow-Grenzen: Sie geht von jeder ShadowRoot zu deren Host-Element weiter und landet am Ende beim Document, wenn der Knoten eingehängt ist, sonst beim obersten losgelösten Knoten. So lässt sich zuverlässig prüfen, ob ein Knoten im „flachen“ Gesamtbaum des Dokuments hängt.

Parameter

Name Typ Default Beschreibung
$options Object { composed: false } Optionales Konfigurationsobjekt.
$options.composed boolean false Bei true werden Shadow-Grenzen überschritten und der Rückgabewert ist die Wurzel des gesamten Baums (meist Document). Bei false endet die Suche an der nächsten ShadowRoot.

Rückgabewert

Typ
Node
Beschreibung
Der Wurzelknoten: meist ein Document oder eine ShadowRoot, bei losgelösten Teilbäumen ein beliebiger Node (etwa ein Element oder DocumentFragment) oder der Knoten selbst.

Beispiele

Wurzel im normalen Dokument und bei losgelösten Knoten

const p = document.createElement('p');
console.log(p.getRootNode() === p); // noch nicht eingehängt

const wrapper = document.createElement('div');
wrapper.append(p);
console.log(p.getRootNode() === wrapper); // oberster Knoten des Teilbaums

document.body.append(wrapper);
console.log(p.getRootNode() === document);
true true true

Shadow Root vs. composed: true

const host = document.createElement('div');
document.body.append(host);
const shadow = host.attachShadow({ mode: 'open' });
const button = document.createElement('button');
shadow.append(button);

console.log(button.getRootNode() === shadow);
console.log(button.getRootNode() instanceof ShadowRoot);
console.log(button.getRootNode({ composed: true }) === document);
true true true

Web Component: im eigenen Baum suchen

class FieldLabel extends HTMLElement {
  connectedCallback() {
    // Funktioniert sowohl im Dokument als auch im Shadow DOM einer anderen Komponente
    const root = this.getRootNode();
    const target = root.getElementById(this.getAttribute('for'));
    this.textContent = target ? `Label für #${target.id}` : 'Ziel nicht gefunden';
  }
}
customElements.define('field-label', FieldLabel);

const host = document.createElement('div');
document.body.append(host);
const shadow = host.attachShadow({ mode: 'open' });
shadow.innerHTML = '<input id="email"><field-label for="email"></field-label>';
console.log(shadow.querySelector('field-label').textContent);
Label für #email

Prüfen, ob ein Knoten wirklich im Dokument hängt

const isInDocument = (node) =>
  node.getRootNode({ composed: true }) === document;

const el = document.createElement('span');
console.log(isInDocument(el));
document.body.append(el);
console.log(isInDocument(el));
false true

// Wichtig · Fallstricke

  • Ohne composed: true ist der Rückgabewert bei Knoten im Shadow DOM eine ShadowRoot und nicht document. Ein Vergleich mit document geht dann still schief.
  • Für die reine Frage „Hängt der Knoten im Dokument?“ ist node.isConnected kürzer und schneller. Es liefert dasselbe wie getRootNode({ composed: true }) === document.
  • Die Methode überschreitet auch geschlossene Shadow Roots (mode: 'closed'), wenn der Aufruf von innen kommt, und gibt dann die geschlossene ShadowRoot zurück. Von außen ist sie nicht erreichbar, weil man keinen Zugriff auf die inneren Knoten hat.
  • Knoten in einem <template> gehören zum Inhalts-Fragment. Ihre Wurzel ist deshalb das DocumentFragment aus template.content, nicht das Dokument.
  • Der Aufwand wächst mit der Tiefe des Baums, weil die Methode die Elternkette durchläuft. In Hot Paths das Ergebnis zwischenspeichern.
  • Nicht unterstützt im Internet Explorer und in Edge-Versionen vor 79 (Legacy). Dort braucht man ein Polyfill, das über parentNode und host läuft.