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

CustomStateSet.forEach()

Methode

Führt eine Callback-Funktion einmal für jeden benutzerdefinierten Zustand im <code>CustomStateSet</code> aus, und zwar in Einfügereihenfolge.

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

Signatur

CustomStateSet.prototype.forEach(callbackFn, thisArg)

Beschreibung

Die Methode forEach() der Schnittstelle CustomStateSet ruft die übergebene Funktion einmal für jeden Eintrag der Menge auf. Ein CustomStateSet erhalten Sie über ElementInternals.states. Es enthält die benutzerdefinierten Zustände eines autonomen Custom Elements. Diese Zustände lassen sich in CSS mit der Pseudoklasse :state(name) abfragen.

Die Methode verhält sich wie Set.prototype.forEach(): Der Callback bekommt den Wert zweimal übergeben, als value und als key (Sets haben keine eigenen Schlüssel), und dazu das Set selbst. Die Reihenfolge entspricht der Einfügereihenfolge.

In der Praxis brauchen Sie forEach() für Debugging, zum Protokollieren, zum Spiegeln der Zustände in Attribute oder ARIA-Eigenschaften und zum Übertragen von Zuständen auf andere Elemente.

Parameter

Name Typ Default Beschreibung
$callbackFn Pflicht (value: string, key: string, set: CustomStateSet) => void Wird für jeden Zustand aufgerufen. Argumente: value (Name des Zustands), key (derselbe Wert wie value) und set (das durchlaufene CustomStateSet).
$thisArg any undefined Wert, der beim Aufruf von callbackFn als this gilt. Bei Pfeilfunktionen hat er keine Wirkung.

Rückgabewert

Typ
undefined
Beschreibung
Die Methode gibt immer undefined zurück und lässt sich deshalb nicht verketten.

Beispiele

Alle Zustände eines Custom Elements protokollieren

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

  constructor() {
    super();
    this.#internals.states.add('bereit');
    this.#internals.states.add('aktiv');
  }

  logStates() {
    this.#internals.states.forEach((value, key, set) => {
      console.log(`Zustand: ${value} (key === value: ${key === value})`);
    });
  }
}

customElements.define('toggle-button', ToggleButton);
const btn = document.createElement('toggle-button');
btn.logStates();
Zustand: bereit (key === value: true) Zustand: aktiv (key === value: true)

Zustände als data-Attribute spiegeln (z. B. für ältere CSS-Selektoren)

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

  setStatus(...states) {
    this.#internals.states.clear();
    states.forEach((s) => this.#internals.states.add(s));
    this.#syncAttributes();
  }

  #syncAttributes() {
    // alte data-state-*-Attribute entfernen
    [...this.attributes]
      .filter((a) => a.name.startsWith('data-state-'))
      .forEach((a) => this.removeAttribute(a.name));

    this.#internals.states.forEach((state) => {
      this.setAttribute(`data-state-${state}`, '');
    });
  }
}

customElements.define('status-badge', StatusBadge);
const badge = document.body.appendChild(document.createElement('status-badge'));
badge.setStatus('online', 'beschaeftigt');
console.log(badge.outerHTML);
<status-badge data-state-online="" data-state-beschaeftigt=""></status-badge>

thisArg nutzen, um Zustände zu sammeln

class InfoCard extends HTMLElement {
  #internals = this.attachInternals();
  constructor() {
    super();
    this.#internals.states.add('geladen');
    this.#internals.states.add('erweitert');
  }
  collect() {
    const collector = { list: [] };
    this.#internals.states.forEach(function (state) {
      this.list.push(state.toUpperCase());
    }, collector);
    return collector.list;
  }
}

customElements.define('info-card', InfoCard);
console.log(document.createElement('info-card').collect());
["GELADEN", "ERWEITERT"]

// Wichtig · Fallstricke

  • Nur über ElementInternals erreichbar: Ein CustomStateSet hat keinen öffentlichen Konstruktor. Sie bekommen es ausschließlich über this.attachInternals().states in einem autonomen Custom Element. attachInternals() darf pro Element nur einmal aufgerufen werden.
  • Änderungen während der Iteration: Wie bei Set werden Zustände, die während des Durchlaufs hinzukommen, noch besucht. Gelöschte, noch nicht besuchte Zustände werden übersprungen. Wenn Sie die Menge beim Durchlaufen verändern wollen, erstellen Sie besser vorher eine Kopie mit [...states].
  • Kein Abbruch möglich: forEach() lässt sich nicht mit break beenden. Brauchen Sie einen Abbruch, verwenden Sie for...of über states.values() oder direkt über states.
  • Syntax der Zustandsnamen: Ältere Chromium-Versionen (vor 125) verlangten Namen im Format --name und den CSS-Selektor :--name. Heute gelten einfache Bezeichner und :state(name). Beim Durchlaufen sehen Sie den Namen so, wie er hinzugefügt wurde.
  • Kompatibilität: Seit 2024 in allen aktuellen Browsern verfügbar (Chrome/Edge 125, Firefox 126, Safari 17.4). Für ältere Browser prüfen Sie vorher mit 'states' in ElementInternals.prototype, ob die Funktion vorhanden ist.