Signatur
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
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();
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);
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());
// Wichtig · Fallstricke
- Nur über ElementInternals erreichbar: Ein
CustomStateSethat keinen öffentlichen Konstruktor. Sie bekommen es ausschließlich überthis.attachInternals().statesin einem autonomen Custom Element.attachInternals()darf pro Element nur einmal aufgerufen werden. - Änderungen während der Iteration: Wie bei
Setwerden 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 mitbreakbeenden. Brauchen Sie einen Abbruch, verwenden Siefor...ofüberstates.values()oder direkt überstates. - Syntax der Zustandsnamen: Ältere Chromium-Versionen (vor 125) verlangten Namen im Format
--nameund 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.