Start · Sprachen · JavaScript · Referenz · HTMLElement: beforetoggle

HTMLElement: beforetoggle

Ereignis

Wird bei einem Popover- oder <code>&lt;dialog&gt;</code>-Element ausgelöst, direkt bevor es angezeigt oder verborgen wird; das Öffnen lässt sich hier noch abbrechen.

seit JavaScript Baseline 2024 für Popover (Chrome 114, Firefox 125 Kategorie: webapi

Signatur

element.addEventListener("beforetoggle", handler)

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

Typ
void
Beschreibung
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();
Popover wird geöffnet closed → open

Ö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'));
Öffnen abgebrochen: bitte zuerst anmelden false

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
beforetoggle: open beforetoggle: closed

// Wichtig · Fallstricke

  • Nur das Öffnen lässt sich abbrechen: preventDefault() wirkt nur, wenn newState === "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: beforetoggle wird synchron vor der Änderung ausgelöst. Das anschließende toggle-Ereignis kommt dagegen asynchron, und mehrere schnelle Wechsel können zu einem einzigen toggle zusammengefasst werden.
  • Wenn man im Handler denselben Zustand erneut ändert (z. B. hidePopover() beim Öffnen), kann das zu Ausnahmen (InvalidStateError) oder unerwartetem Verhalten führen. Besser preventDefault() verwenden.
  • Öffnet man ein popover="auto", werden andere automatische Popovers geschlossen. Diese lösen dann ebenfalls beforetoggle mit newState: "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.