Signatur
Beschreibung
Das toggle-Ereignis meldet, dass ein Element seinen Sichtbarkeitszustand geändert hat. Es tritt bei drei Elementarten auf: bei Elementen mit dem Attribut popover, bei <dialog> und bei <details>. Das Ereignis wird nach der Zustandsänderung ausgelöst, ist nicht abbrechbar und steigt nicht im DOM auf (kein Bubbling).
Bei Popover- und Dialog-Elementen ist das Ereignisobjekt ein ToggleEvent mit den Eigenschaften oldState und newState (jeweils "open" oder "closed"). Bei <details> liefern aktuelle Browser ebenfalls einen ToggleEvent; in älteren Browsern ist es ein einfaches Event – dort prüft man stattdessen details.open.
Typische Einsatzzwecke: Zustand speichern (z. B. aufgeklappte Abschnitte in localStorage), Inhalte beim ersten Öffnen nachladen, Analyse-Ereignisse senden oder Aufräumarbeiten nach dem Schließen durchführen. Wer eine Änderung verhindern will, nutzt stattdessen das Ereignis beforetoggle, das vor der Änderung feuert und bei Popovers (beim Öffnen) abbrechbar ist.
Man registriert den Handler per addEventListener("toggle", handler) oder über die Eigenschaft element.ontoggle.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "toggle". |
|
| $handler Pflicht | (event: ToggleEvent | Event) => void | Callback, der nach dem Öffnen/Schließen aufgerufen wird. event.newState und event.oldState geben den Zustand an. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once, signal oder capture. Da toggle nicht aufsteigt, ist capture: true nötig, um es an einem Vorfahren abzufangen. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler erhält ein ToggleEvent (bei älteren <details>-Implementierungen ein Event).Beispiele
Popover-Zustand mit addEventListener überwachen
// HTML: <button popovertarget="menu">Menü</button>
// <div id="menu" popover>Inhalt</div>
const menu = document.getElementById('menu');
menu.addEventListener('toggle', (event) => {
console.log(`Popover: ${event.oldState} → ${event.newState}`);
});
menu.showPopover();
Aufgeklappte details-Abschnitte in localStorage merken
// HTML: <details id="faq-1"><summary>Frage</summary>Antwort</details>
const details = document.querySelectorAll('details[id]');
for (const el of details) {
el.open = localStorage.getItem(el.id) === 'open';
el.addEventListener('toggle', () => {
localStorage.setItem(el.id, el.open ? 'open' : 'closed');
});
}
Inhalt beim ersten Öffnen nachladen und Listener entfernen
const panel = document.querySelector('details#bericht');
const loadOnce = async () => {
if (!panel.open) return;
panel.removeEventListener('toggle', loadOnce);
const res = await fetch('/api/bericht');
panel.querySelector('.inhalt').textContent = await res.text();
};
panel.addEventListener('toggle', loadOnce);
ontoggle-Property bei einem dialog
const dialog = document.querySelector('dialog');
dialog.ontoggle = (event) => {
if (event.newState === 'closed') {
console.log('Dialog geschlossen, Rückgabewert:', dialog.returnValue);
}
};
dialog.showModal();
dialog.close('ok');
// Handler wieder entfernen
// dialog.ontoggle = null;
// Wichtig · Fallstricke
- Kein Bubbling:
togglesteigt nicht auf. Für Delegation an einem ContaineraddEventListener('toggle', fn, { capture: true })verwenden. - Nicht abbrechbar:
preventDefault()bewirkt nichts. Zum Verhindern des Öffnens eines Popoversbeforetogglenutzen. - Zusammenfassung schneller Wechsel: Wird ein Element mehrmals kurz hintereinander umgeschaltet, feuert der Browser unter Umständen nur ein einziges
toggle-Ereignis (Koaleszierung). Daher immernewStatebzw.element.openauswerten, statt Aufrufe zu zählen. - Asynchron: Das Ereignis wird als Task eingereiht, nicht synchron während
showPopover()/open = trueausgelöst. - Auch das programmatische Setzen von
details.openlösttoggleaus – Vorsicht vor Endlosschleifen, wenn man im Handler den Zustand erneut ändert. - Kompatibilität:
<details>-toggle wird überall unterstützt; Popover-toggle ist seit 2024 Baseline.togglebei<dialog>ist neu (Chrome 132, Firefox 133, Safari 18.4) – für ältere Browser aufclose-Ereignis zurückgreifen.ToggleEventbei<details>gibt es ebenfalls erst in neueren Versionen.