Start · Sprachen · JavaScript · Referenz · HTMLElement: toggle

HTMLElement: toggle

Ereignis

Wird bei einem Popover-, <code>&lt;dialog&gt;</code>- oder <code>&lt;details&gt;</code>-Element ausgelöst, direkt nachdem es geöffnet oder geschlossen wurde.

seit JavaScript Baseline: details seit Langem in allen Browsern; P Kategorie: webapi

Signatur

element.addEventListener("toggle", handler)

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

Typ
void
Beschreibung
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();
Popover: closed → open

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;
Dialog geschlossen, Rückgabewert: ok

// Wichtig · Fallstricke

  • Kein Bubbling: toggle steigt nicht auf. Für Delegation an einem Container addEventListener('toggle', fn, { capture: true }) verwenden.
  • Nicht abbrechbar: preventDefault() bewirkt nichts. Zum Verhindern des Öffnens eines Popovers beforetoggle nutzen.
  • Zusammenfassung schneller Wechsel: Wird ein Element mehrmals kurz hintereinander umgeschaltet, feuert der Browser unter Umständen nur ein einziges toggle-Ereignis (Koaleszierung). Daher immer newState bzw. element.open auswerten, statt Aufrufe zu zählen.
  • Asynchron: Das Ereignis wird als Task eingereiht, nicht synchron während showPopover()/open = true ausgelöst.
  • Auch das programmatische Setzen von details.open löst toggle aus – 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. toggle bei <dialog> ist neu (Chrome 132, Firefox 133, Safari 18.4) – für ältere Browser auf close-Ereignis zurückgreifen. ToggleEvent bei <details> gibt es ebenfalls erst in neueren Versionen.