Signatur
Beschreibung
Mit customElements.upgrade(root) durchläuft der Browser den gesamten Unterbaum von root in der Reihenfolge des Dokuments und wertet jedes Element auf, zu dessen Tag-Namen schon eine Definition registriert ist. Dabei werden auch Shadow Roots durchsucht. Das meint die Bezeichnung „shadow-including“, die in manchen Übersetzungen als „schattenhaltig“ auftaucht. Aufwerten heißt: Der Konstruktor der Klasse läuft, und das Element wird zu einer echten Instanz dieser Klasse, mit allen ihren Methoden und Eigenschaften.
Normalerweise werden benutzerdefinierte Elemente erst aufgewertet, wenn sie mit dem Dokument verbunden werden, also z. B. per appendChild() in den DOM-Baum kommen. Ein Element, das Sie per document.createElement() erzeugt haben, bevor customElements.define() lief, bleibt deshalb ein einfaches HTMLElement, solange es nicht im Dokument steckt. Mit upgrade() erzwingen Sie das Aufwerten früher. So können Sie Eigenschaften oder Methoden der Klasse schon nutzen, bevor der Baum angezeigt wird.
Typische Einsatzfälle:
- Komponenten-Bäume, die außerhalb des Dokuments vorbereitet und konfiguriert werden, bevor sie eingehängt werden.
- Elemente, die vor dem Laden oder Registrieren der Komponenten-Definition entstanden sind (z. B. bei nachgeladenen Modulen).
- Aus einem
<template>importierte Inhalte, deren Komponenten sofort per Code ansprechbar sein sollen.
Das Aufwerten läuft synchron: Sobald upgrade() zurückkehrt, sind alle passenden Elemente Instanzen ihrer Klasse. Der connectedCallback läuft dabei allerdings nicht, denn die Elemente sind ja noch nicht verbunden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $root Pflicht | Node | Knoten, bei dem die Suche beginnt. Der Knoten selbst, alle seine Nachfahren und die Inhalte angehängter Shadow Roots werden geprüft. Kein Node übergeben → TypeError. |
Rückgabewert
Beispiele
Vor der Definition erzeugtes Element aufwerten
// Element entsteht, bevor die Definition existiert
const el = document.createElement('spider-man');
class SpiderMan extends HTMLElement {
greet() {
return 'Hallo aus der Komponente!';
}
}
customElements.define('spider-man', SpiderMan);
console.log(el instanceof SpiderMan); // noch nicht verbunden → false
customElements.upgrade(el);
console.log(el instanceof SpiderMan);
console.log(el.greet());
Komponenten-Baum mit Shadow Root vor dem Einhängen konfigurieren
class UserCard extends HTMLElement {
#name = '';
set name(value) { this.#name = value; }
get name() { return this.#name; }
connectedCallback() {
this.textContent = `Benutzer: ${this.#name}`;
}
}
// Baum wird vor der Definition gebaut, eine Karte liegt im Shadow DOM
const host = document.createElement('div');
const shadow = host.attachShadow({ mode: 'open' });
shadow.innerHTML = '<user-card></user-card>';
customElements.define('user-card', UserCard);
// Ohne upgrade() wäre der Setter noch nicht vorhanden
customElements.upgrade(host);
const card = shadow.querySelector('user-card');
card.name = 'Ada Lovelace'; // läuft jetzt über den Setter der Klasse
console.log(card instanceof UserCard);
document.body.append(host); // connectedCallback rendert den Namen
console.log(card.textContent);
Template-Inhalt importieren und sofort ansprechen
class ToggleButton extends HTMLElement {
pressed = false;
toggle() {
this.pressed = !this.pressed;
return this.pressed;
}
}
customElements.define('toggle-button', ToggleButton);
const tpl = document.createElement('template');
tpl.innerHTML = '<section><toggle-button></toggle-button></section>';
// Template-Inhalt gehört zu einem inerten Dokument → erst importieren
const fragment = document.importNode(tpl.content, true);
customElements.upgrade(fragment);
const btn = fragment.querySelector('toggle-button');
console.log(btn.toggle());
document.body.append(fragment);
// Wichtig · Fallstricke
- Nur registrierte Elemente:
upgrade()wertet nur Elemente auf, deren Definition schon percustomElements.define()registriert ist. Wird eine Definition erst später registriert, müssen Sieupgrade()erneut aufrufen oder die Elemente einhängen. - Kein
connectedCallback: Beim Aufwerten laufen der Konstruktor und, falls beobachtete Attribute vorhanden sind, derattributeChangedCallback. DerconnectedCallbackläuft erst beim Einhängen in das Dokument. - Template-Inhalte:
template.contentgehört zu einem eigenen, inerten Dokument ohne Registry. Ein direkterupgrade()-Aufruf darauf bewirkt nichts. Übernehmen Sie den Inhalt zuerst mitdocument.importNode()oderadoptNode(). - Vorher gesetzte Eigenschaften: Weisen Sie einem Element vor dem Aufwerten eine Eigenschaft zu, überdeckt diese als eigene Eigenschaft der Instanz den Setter der Klasse. Deshalb entweder vorher
upgrade()aufrufen oder im Konstruktor bzw.connectedCallbacksolche Werte übernehmen (bekanntes „lazy property“-Muster). - Bereits aufgewertete Elemente werden übersprungen. Der Konstruktor läuft nie doppelt.
- Kompatibilität: Wird von allen modernen Browsern unterstützt, nicht aber vom Internet Explorer. In Node.js gibt es diese Methode nicht; hier braucht man eine DOM-Umgebung wie jsdom oder happy-dom.