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

CustomStateSet.values()

Methode

Gibt einen neuen Iterator zurück, der alle benutzerdefinierten Zustände eines <code>CustomStateSet</code> in Einfügereihenfolge liefert.

seit JavaScript Baseline 2024: Chrome 125, Edge 125, Firefox 126, Kategorie: webapi

Signatur

CustomStateSet.prototype.values()

Beschreibung

Die Methode values() des CustomStateSet gibt ein neues Iterator-Objekt zurück. Es liefert jeden benutzerdefinierten Zustand (einen String wie "checked" oder "loading") eines Custom Elements, und zwar in der Reihenfolge, in der die Zustände mit add() hinzugefügt wurden.

Ein CustomStateSet bekommt man über ElementInternals.states, also innerhalb eines Custom Elements nach dem Aufruf von this.attachInternals(). Die Zustände darin lassen sich in CSS mit der Pseudoklasse :state(name) abfragen. Mit values() kann man den aktuellen Zustand der Komponente auslesen, etwa zum Debuggen, zum Protokollieren oder um ihn zu serialisieren.

CustomStateSet verhält sich wie ein Set. Deshalb ist values() identisch mit keys() und auch mit [Symbol.iterator](). Ein Aufruf von for...of direkt auf dem Set oder die Spread-Syntax [...states] nutzt intern denselben Iterator.

Rückgabewert

Typ
Iterator<string>
Beschreibung
Ein neuer Set-Iterator. Jeder Schritt liefert { value: string, done: boolean } mit dem Namen eines benutzerdefinierten Zustands.

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('on') ? states.delete('on') : states.add('on');
  }

  get currentStates() {
    return [...this.#internals.states.values()];
  }
}

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

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

Iterator schrittweise mit next() durchlaufen

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

const box = new StatusBox();
box.internals.states.add('loading');
box.internals.states.add('error');

const it = box.internals.states.values();
console.log(it.next()); // erster Zustand
console.log(it.next()); // zweiter Zustand
console.log(it.next()); // Ende erreicht
{ value: "loading", done: false } { value: "error", done: false } { value: undefined, done: true }

Zustände für Debug-Ausgabe als Attribut spiegeln

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

  setState(name, active) {
    const { states } = this.#internals;
    active ? states.add(name) : states.delete(name);
    // Für DevTools sichtbar machen
    this.dataset.states = Array.from(states.values()).join(' ');
  }
}
customElements.define('form-field', FormField);

const field = document.createElement('form-field');
field.setState('invalid', true);
field.setState('touched', true);
console.log(field.dataset.states);
invalid touched

// Wichtig · Fallstricke

  • Live-Iterator: Der Iterator ist keine Momentaufnahme. Zustände, die während des Durchlaufens hinzugefügt oder entfernt werden, wirken sich auf die restliche Iteration aus. Wer eine feste Kopie braucht, sollte vorher [...states.values()] erzeugen.
  • Nur intern erreichbar: Das CustomStateSet hängt am ElementInternals-Objekt. Speichert man internals privat (#internals), kann Code von außen die Zustände nicht auslesen. Das ist so gewollt und schützt die Kapselung.
  • Kompatibilität: Die heutige Form mit Zustandsnamen ohne Präfix und der CSS-Pseudoklasse :state(name) gibt es erst seit Chrome 125, Firefox 126 und Safari 17.4. Ältere Chromium-Versionen (90–124) haben die veraltete Schreibweise --name mit dem Selektor :--name verwendet. Für ältere Browser sollte man die Unterstützung prüfen, z. B. mit CSS.supports('selector(:state(x))').
  • values(), keys() und [Symbol.iterator]() liefern dasselbe Ergebnis. entries() liefert dagegen Paare der Form [wert, wert].