Start · Sprachen · JavaScript · Referenz · HTMLDialogElement: close

HTMLDialogElement: close

Ereignis

Wird auf einem <code>&lt;dialog&gt;</code>-Element ausgelöst, nachdem der Dialog geschlossen wurde – egal ob per <code>close()</code>, Formular mit <code>method="dialog"</code> oder Escape-Taste.

seit JavaScript Baseline: alle modernen Browser (seit 2022) Kategorie: webapi

Signatur

dialog.addEventListener("close", handler)

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

Typ
void
Beschreibung
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 geschlossen mit: ok Eintrag wird gelöscht …

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);
Bestätigt

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;
onclose: geschlossen Listener: close, bubbles=false, cancelable=false

// Wichtig · Fallstricke

  • Nicht abbrechbar: preventDefault() im close-Handler bewirkt nichts, denn der Dialog ist dann schon zu. Wer das Schließen verhindern will, nimmt das cancel-Ereignis. Ab Chrome 126 lässt sich cancel allerdings 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 nach dialog.close() läuft also vor dem Handler.
  • Nur bei offenem Dialog: close() auf einem bereits geschlossenen Dialog löst kein Ereignis aus. Wird das open-Attribut direkt entfernt (dialog.removeAttribute('open')), feuert close ebenfalls nicht. Deshalb immer close() verwenden.
  • returnValue bleibt erhalten: Der Wert wird beim erneuten Öffnen nicht automatisch zurückgesetzt. Vor showModal() also manuell returnValue = '' setzen.
  • Blubbert nicht: Delegation über document klappt nur mit { capture: true }.
  • Kompatibilität: <dialog> und das close-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.