Start · Sprachen · JavaScript · Referenz · CustomStateSet.keys()

CustomStateSet.keys()

Methode

Gibt einen neuen Iterator über alle Zustände eines <code>CustomStateSet</code> in Einfügereihenfolge zurück – ein Alias für <code>CustomStateSet.values()</code>.

seit JavaScript Baseline 2024: Chrome 125, Firefox 126, Safari 17. Kategorie: webapi

Signatur

CustomStateSet.prototype.keys()

Beschreibung

Die Methode keys() der Schnittstelle CustomStateSet gibt einen neuen Set-Iterator zurück. Er liefert alle benutzerdefinierten Zustände eines Custom Elements in der Reihenfolge, in der sie hinzugefügt wurden. Diese Zustände setzt man über ElementInternals.states.

Ein CustomStateSet verhält sich wie ein Set. Anders als bei einer Map gibt es keine getrennten Schlüssel. Deshalb ist keys() nur ein Alias für values(): Beide Methoden liefern dieselben Zeichenketten, zum Beispiel "checked" oder "loading". Die Methode gibt es vor allem, damit die Schnittstelle zu Map und Set passt.

Nützlich ist keys() in diesen Fällen:

  • Fehlersuche: Welche Zustände hat eine Komponente gerade?
  • Zustände serialisieren oder protokollieren
  • Generischer Code, der mit beliebigen Set- oder Map-artigen Sammlungen über keys() arbeitet

Im CSS fragt man die Zustände mit der Pseudoklasse :state(name) ab.

Rückgabewert

Typ
SetIterator<string>
Beschreibung
Ein neuer Iterator. Er liefert jeden Zustandsnamen (string) des CustomStateSet in Einfügereihenfolge, genau wie values().

Beispiele

Zustände eines Custom Elements auflisten

class ToggleButton extends HTMLElement {
  #internals = this.attachInternals();

  constructor() {
    super();
    this.#internals.states.add('ready');
    this.addEventListener('click', () => this.toggle());
  }

  toggle() {
    const { states } = this.#internals;
    states.has('checked') ? states.delete('checked') : states.add('checked');
  }

  get activeStates() {
    // keys() liefert dieselben Werte wie values()
    return [...this.#internals.states.keys()];
  }
}

customElements.define('toggle-button', ToggleButton);

const btn = document.createElement('toggle-button');
document.body.append(btn);
btn.click();
console.log(btn.activeStates);
["ready", "checked"]

Iterator von Hand mit next() durchlaufen

class StatusBadge extends HTMLElement {
  internals = this.attachInternals();
}
customElements.define('status-badge', StatusBadge);

const badge = new StatusBadge();
badge.internals.states.add('online');
badge.internals.states.add('busy');

const it = badge.internals.states.keys();
console.log(it.next()); // erster Zustand
console.log(it.next()); // zweiter Zustand
console.log(it.next()); // Ende erreicht
{ value: "online", done: false } { value: "busy", done: false } { value: undefined, done: true }

keys() und values() sind gleichwertig

class DemoEl extends HTMLElement {
  internals = this.attachInternals();
}
customElements.define('demo-el', DemoEl);

const el = new DemoEl();
el.internals.states.add('loading');

const viaKeys = [...el.internals.states.keys()];
const viaValues = [...el.internals.states.values()];
console.log(viaKeys, viaValues);
console.log(JSON.stringify(viaKeys) === JSON.stringify(viaValues));
["loading"] ["loading"] true

// Wichtig · Fallstricke

  • Nur ein Alias: Für Lesbarkeit ist values() oder direktes Iterieren (for...of) meist klarer. keys() hat keine zusätzliche Funktion.
  • Einmal verbrauchbar: Ein durchlaufener Iterator bleibt leer. Für eine zweite Iteration keys() erneut aufrufen oder das Ergebnis mit [...iter] bzw. Array.from() in ein Array kopieren.
  • Live-Verhalten: Wird das Set während der Iteration verändert, erscheinen neu hinzugefügte Zustände noch im Iterator. Entfernte, noch nicht besuchte Zustände werden übersprungen.
  • Browser-Kompatibilität: Voll unterstützt seit Chrome/Edge 125, Firefox 126 und Safari 17.4. Ältere Chromium-Versionen (90–124) erlaubten nur Zustandsnamen mit ---Präfix und die CSS-Syntax :--name statt :state(name). Vorher per Feature-Test prüfen: 'states' in ElementInternals.prototype.
  • Die Zustände sind nur über ElementInternals erreichbar. Diese Objekte sollte man als privates Feld kapseln, damit fremder Code die Zustände nicht verändert.