Signatur
Beschreibung
Das close-Ereignis tritt ein, nachdem ein <dialog>-Element geschlossen wurde. Es spielt keine Rolle, wie das passiert ist: durch den Aufruf von HTMLDialogElement.close(), durch das Absenden eines Formulars mit method="dialog", durch die Escape-Taste bei modalen Dialogen (showModal()) oder durch requestClose(). Registriert wird der Handler mit addEventListener("close", handler) oder über die Eigenschaft onclose.
Typischerweise wertet man im Handler dialog.returnValue aus. Diese Eigenschaft enthält den Wert, der an close(wert) übergeben wurde, oder den value des Buttons, mit dem ein method="dialog"-Formular abgeschickt wurde. So lässt sich ein Bestätigungsdialog („OK“/„Abbrechen“) sauber auswerten, ohne auf jeden Button einzeln zu hören.
Das Ereignis ist ein einfaches Event. Es ist nicht abbrechbar und blubbert nicht (bubbles: false). Wer das Schließen verhindern will, muss stattdessen das cancel-Ereignis nutzen. Das feuert nur beim Schließen durch Escape bzw. requestClose() und kann mit preventDefault() abgebrochen werden.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $type Pflicht | string | Der Ereignistyp, hier immer "close". |
|
| $handler Pflicht | (event: Event) => void | Callback, das nach dem Schließen aufgerufen wird. Es bekommt ein gewöhnliches Event-Objekt, dessen target das Dialog-Element ist. |
|
| $options | boolean | AddEventListenerOptions | false | Optionen wie once, signal oder capture. Weil das Ereignis nicht blubbert, braucht man capture: true, um es auf einem Vorfahren-Element abzufangen. |
Rückgabewert
addEventListener gibt nichts zurück. Das Ereignisobjekt ist vom Typ Event.Beispiele
Bestätigungsdialog mit returnValue auswerten
// HTML:
// <dialog id="confirm">
// <form method="dialog">
// <p>Eintrag wirklich löschen?</p>
// <button value="cancel">Abbrechen</button>
// <button value="ok">Löschen</button>
// </form>
// </dialog>
// <button id="delete">Löschen…</button>
const dialog = document.getElementById('confirm');
dialog.addEventListener('close', () => {
// returnValue = value des Buttons, mit dem das Formular abgeschickt wurde
console.log(`Dialog geschlossen mit: ${dialog.returnValue}`);
if (dialog.returnValue === 'ok') {
console.log('Eintrag wird gelöscht …');
}
});
document.getElementById('delete').addEventListener('click', () => {
dialog.returnValue = ''; // alten Wert zurücksetzen
dialog.showModal();
});
Dialog als Promise (async/await) mit einmaligem Listener
const askUser = (dialog) => new Promise((resolve) => {
dialog.returnValue = '';
// once: true entfernt den Listener nach dem ersten Aufruf automatisch
dialog.addEventListener('close', () => resolve(dialog.returnValue), { once: true });
dialog.showModal();
});
const dialog = document.querySelector('dialog');
const run = async () => {
const answer = await askUser(dialog);
console.log(answer === 'ok' ? 'Bestätigt' : 'Abgebrochen');
};
run();
// Irgendwo später, z. B. aus einem Button-Handler:
setTimeout(() => dialog.close('ok'), 1000);
onclose-Eigenschaft und removeEventListener
const dialog = document.querySelector('dialog');
// Variante 1: on-Property (nur ein Handler möglich)
dialog.onclose = () => console.log('onclose: geschlossen');
// Variante 2: benannter Listener, der wieder entfernt werden kann
const logClose = (event) => {
console.log(`Listener: ${event.type}, bubbles=${event.bubbles}, cancelable=${event.cancelable}`);
};
dialog.addEventListener('close', logClose);
dialog.show();
dialog.close();
// Listener wieder abmelden
dialog.removeEventListener('close', logClose);
dialog.onclose = null;
// Wichtig · Fallstricke
- Nicht abbrechbar:
preventDefault()imclose-Handler bewirkt nichts, denn der Dialog ist dann schon zu. Wer das Schließen verhindern will, nimmt dascancel-Ereignis. Ab Chrome 126 lässt sichcancelallerdings nicht bei jedem Escape-Druck abbrechen, wenn kein Nutzerkontakt stattgefunden hat. - Asynchron: Das Ereignis wird als Task in die Warteschlange gestellt und läuft deshalb nicht synchron innerhalb von
close(). Code direkt nachdialog.close()läuft also vor dem Handler. - Nur bei offenem Dialog:
close()auf einem bereits geschlossenen Dialog löst kein Ereignis aus. Wird dasopen-Attribut direkt entfernt (dialog.removeAttribute('open')), feuertcloseebenfalls nicht. Deshalb immerclose()verwenden. - returnValue bleibt erhalten: Der Wert wird beim erneuten Öffnen nicht automatisch zurückgesetzt. Vor
showModal()also manuellreturnValue = ''setzen. - Blubbert nicht: Delegation über
documentklappt nur mit{ capture: true }. - Kompatibilität:
<dialog>und dasclose-Ereignis gehören seit März 2022 zur Baseline (Chrome 37+, Firefox 98+, Safari 15.4+).requestClose()ist neuer und noch nicht überall verfügbar.