Signatur
Beschreibung
Das Ereignis beforetoggle wird bei Elementen mit dem Attribut popover und bei <dialog>-Elementen ausgelöst, bevor sich ihr Sichtbarkeitszustand ändert. Das passiert etwa bei showPopover(), hidePopover(), togglePopover(), einem Klick auf einen Button mit popovertarget, einem Light-Dismiss (Klick außerhalb, Esc) oder bei dialog.show(), showModal() und close().
Der Handler bekommt ein ToggleEvent. Die Eigenschaften oldState und newState enthalten jeweils "open" oder "closed". So erkennt man, ob das Element gerade geöffnet oder geschlossen wird. Solange das Element geöffnet wird (newState === "open"), lässt sich das Ereignis abbrechen: event.preventDefault() verhindert dann, dass das Popover oder der Dialog erscheint. Beim Schließen lässt es sich nicht abbrechen.
Typische Einsatzfälle sind: Inhalte kurz vor dem Anzeigen nachladen oder aktualisieren, das Öffnen an Bedingungen knüpfen (z. B. ungespeicherte Formulardaten), Analyse-Ereignisse erfassen oder andere Popovers schließen. Man registriert den Handler mit addEventListener("beforetoggle", …) oder über die Eigenschaft onbeforetoggle. Soll erst nach der Zustandsänderung etwas passieren, nimmt man das Ereignis toggle.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignisname "beforetoggle". |
|
| $handler Pflicht | (event: ToggleEvent) => void | Callback-Funktion. Sie erhält ein ToggleEvent mit oldState und newState ("open" | "closed"). |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once, signal oder capture. |
Rückgabewert
addEventListener gibt nichts zurück. Der Handler bekommt ein ToggleEvent.Beispiele
Öffnen und Schließen eines Popovers protokollieren
// HTML: <button popovertarget="menu">Menü</button>
// <div id="menu" popover>Inhalt</div>
const menu = document.getElementById('menu');
menu.addEventListener('beforetoggle', (event) => {
if (event.newState === 'open') {
console.log('Popover wird geöffnet');
} else {
console.log('Popover wird geschlossen');
}
console.log(`${event.oldState} → ${event.newState}`);
});
menu.showPopover();
Öffnen verhindern, solange eine Bedingung nicht erfüllt ist
const hilfe = document.getElementById('hilfe'); // <div id="hilfe" popover>
let eingeloggt = false;
hilfe.addEventListener('beforetoggle', (event) => {
// Abbrechen lässt sich nur das Öffnen
if (event.newState === 'open' && !eingeloggt) {
event.preventDefault();
console.log('Öffnen abgebrochen: bitte zuerst anmelden');
}
});
hilfe.showPopover();
console.log(hilfe.matches(':popover-open'));
Dialog-Inhalt vor dem Anzeigen aktualisieren (onbeforetoggle)
// HTML: <dialog id="info"><p id="zeit"></p><button>OK</button></dialog>
const dialog = document.getElementById('info');
const zeit = document.getElementById('zeit');
dialog.onbeforetoggle = (event) => {
if (event.newState === 'open') {
zeit.textContent = `Stand: ${new Date().toLocaleTimeString('de-DE')}`;
}
};
dialog.querySelector('button').addEventListener('click', () => dialog.close());
dialog.showModal();
Handler mit removeEventListener wieder entfernen
const tooltip = document.getElementById('tooltip'); // <div id="tooltip" popover="manual">
const beimUmschalten = (event) => {
console.log('beforetoggle:', event.newState);
};
tooltip.addEventListener('beforetoggle', beimUmschalten);
tooltip.showPopover(); // wird protokolliert
tooltip.hidePopover(); // wird protokolliert
tooltip.removeEventListener('beforetoggle', beimUmschalten);
tooltip.showPopover(); // wird nicht mehr protokolliert
// Wichtig · Fallstricke
- Nur das Öffnen lässt sich abbrechen:
preventDefault()wirkt nur, wennnewState === "open". Beim Schließen hat es keine Wirkung. - Kein Bubbling: Das Ereignis wird nicht an Elternelemente weitergereicht. Für Event-Delegation am Dokument braucht man daher
{ capture: true }. - Synchron statt gebündelt:
beforetogglewird synchron vor der Änderung ausgelöst. Das anschließendetoggle-Ereignis kommt dagegen asynchron, und mehrere schnelle Wechsel können zu einem einzigentogglezusammengefasst werden. - Wenn man im Handler denselben Zustand erneut ändert (z. B.
hidePopover()beim Öffnen), kann das zu Ausnahmen (InvalidStateError) oder unerwartetem Verhalten führen. BesserpreventDefault()verwenden. - Öffnet man ein
popover="auto", werden andere automatische Popovers geschlossen. Diese lösen dann ebenfallsbeforetogglemitnewState: "closed"aus. - Kompatibilität: Für Popovers ist das Ereignis seit 2024 in allen aktuellen Browsern verfügbar (Baseline). Für
<dialog>gibt es Unterstützung erst in neueren Versionen. Deshalb sollte man es dort als Verbesserung behandeln und nicht voraussetzen. Feature-Erkennung:'onbeforetoggle' in HTMLElement.prototype.