Start · Sprachen · JavaScript · Referenz · CustomElementRegistry.upgrade()

CustomElementRegistry.upgrade()

Methode

Wertet alle benutzerdefinierten Elemente im Unterbaum von <code>root</code> einschließlich Shadow Roots sofort auf, auch wenn der Baum noch nicht im Dokument hängt.

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

Signatur

CustomElementRegistry.prototype.upgrade(root)

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

Typ
undefined
Beschreibung
Kein Rückgabewert. Die Methode wirkt nur über ihren Nebeneffekt: Die betroffenen Elemente werden direkt, also ohne neues Objekt, zu Instanzen ihrer Klasse.

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());
false true Hallo aus der Komponente!

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);
true Benutzer: Ada Lovelace

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

// Wichtig · Fallstricke

  • Nur registrierte Elemente: upgrade() wertet nur Elemente auf, deren Definition schon per customElements.define() registriert ist. Wird eine Definition erst später registriert, müssen Sie upgrade() erneut aufrufen oder die Elemente einhängen.
  • Kein connectedCallback: Beim Aufwerten laufen der Konstruktor und, falls beobachtete Attribute vorhanden sind, der attributeChangedCallback. Der connectedCallback läuft erst beim Einhängen in das Dokument.
  • Template-Inhalte: template.content gehört zu einem eigenen, inerten Dokument ohne Registry. Ein direkter upgrade()-Aufruf darauf bewirkt nichts. Übernehmen Sie den Inhalt zuerst mit document.importNode() oder adoptNode().
  • 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. connectedCallback solche 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.