Signatur
Beschreibung
HTMLDialogElement ist die DOM-Schnittstelle des HTML-Elements <dialog>. Damit baut man native Dialogfenster wie Bestätigungsabfragen, Formulare in Overlays oder Hinweisboxen, ohne dafür eine eigene Bibliothek zu brauchen. Das Interface erbt alle Eigenschaften und Methoden von HTMLElement und ergänzt sie um dialogspezifische Funktionen.
Die wichtigsten Mitglieder sind:
showModal()öffnet den Dialog modal. Er liegt dann im Top Layer über allen anderen Inhalten, bekommt einen::backdrop-Hintergrund und macht den restlichen Seiteninhalt inert. Mit Esc lässt er sich schließen.show()öffnet den Dialog nicht-modal. Die restliche Seite bleibt bedienbar.close(returnValue?)schließt den Dialog und setzt optionalreturnValue.requestClose(returnValue?)(neu) schließt den Dialog wie per Esc. Dabei wird zuerstcancelausgelöst, das man abbrechen kann.open(boolean) spiegelt das Attributopenwider.returnValue(string) ist der Rückgabewert des Dialogs, zum Beispiel dervaluedes Buttons, mit dem ein<form method="dialog">abgeschickt wurde.closedBy(neu) legt fest, wie sich der Dialog schließen lässt:"any","closerequest"oder"none".
Die wichtigsten Events sind close (nach dem Schließen), cancel (bei Esc oder einer anderen Schließanforderung, lässt sich abbrechen) sowie beforetoggle und toggle. Ein <form method="dialog"> innerhalb des Dialogs schließt ihn beim Absenden automatisch und schreibt den Wert des auslösenden Buttons in returnValue. Das ist der einfachste Weg, um Antworten wie „Ja/Nein“ auszuwerten.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $returnValue | string | Parameter von close() und requestClose(): Dieser Wert wird beim Schließen in dialog.returnValue geschrieben. |
Rückgabewert
show(), showModal() und close() geben jeweils undefined zurück. Das Ergebnis des Dialogs liest man über returnValue aus.Beispiele
Modalen Dialog öffnen und schließen
// HTML:
// <button id="oeffnen">Einstellungen</button>
// <dialog id="dlg">
// <p>Einstellungen …</p>
// <button id="schliessen">Schließen</button>
// </dialog>
const dialog = document.querySelector('#dlg');
document.querySelector('#oeffnen').addEventListener('click', () => {
dialog.showModal();
console.log('Offen:', dialog.open);
});
document.querySelector('#schliessen').addEventListener('click', () => {
dialog.close();
console.log('Offen:', dialog.open);
});
Bestätigungsdialog als Promise mit form method="dialog"
// HTML:
// <dialog id="confirm">
// <form method="dialog">
// <p>Datei wirklich löschen?</p>
// <button value="nein">Abbrechen</button>
// <button value="ja">Löschen</button>
// </form>
// </dialog>
const bestaetigen = (dialog) => new Promise((resolve) => {
dialog.returnValue = '';
dialog.addEventListener('close', () => resolve(dialog.returnValue === 'ja'), { once: true });
dialog.showModal();
});
const loeschen = async () => {
const ok = await bestaetigen(document.querySelector('#confirm'));
console.log(ok ? 'Datei gelöscht' : 'Abgebrochen');
};
loeschen();
Esc abfangen bei ungespeicherten Änderungen
const dialog = document.querySelector('#editor');
let ungespeichert = true;
dialog.addEventListener('cancel', (event) => {
if (ungespeichert && !window.confirm('Änderungen verwerfen?')) {
event.preventDefault(); // Dialog bleibt offen
}
});
dialog.addEventListener('close', () => {
console.log('Dialog geschlossen, returnValue =', JSON.stringify(dialog.returnValue));
});
dialog.showModal();
Schließen per Klick auf den Backdrop
const dialog = document.querySelector('#info');
dialog.addEventListener('click', (event) => {
// Der Klick auf den ::backdrop hat den Dialog selbst als target
if (event.target === dialog) {
dialog.close('backdrop');
}
});
dialog.addEventListener('close', () => console.log(dialog.returnValue));
dialog.showModal();
// Wichtig · Fallstricke
- Fehler bei showModal(): Ruft man
showModal()auf einem Dialog auf, der schon nicht-modal offen ist (open-Attribut gesetzt) oder nicht im Dokument hängt, wird eineInvalidStateError-DOMExceptiongeworfen. Ist der Dialog bereits modal offen, passiert nichts. - Attribut
opennicht direkt setzen: Setzt man das Attributopenvon Hand, öffnet sich der Dialog nur nicht-modal: ohne Top Layer, ohne Backdrop und ohne Fokusverwaltung. Nutze stattdessenshow()bzw.showModal(). - Backdrop-Klick: Klicks auf den Backdrop schließen den Dialog nicht automatisch. Entweder wertet man
event.target === dialogaus oder nutztclosedBy="any", das derzeit nur in Chromium-basierten Browsern unterstützt wird. cancel-Event: Chrome ignoriertpreventDefault()aufcancel, wenn der Nutzer zweimal hintereinander Esc drückt, ohne dazwischen mit der Seite zu interagieren. Das soll verhindern, dass Nutzer in einem Dialog festsitzen.- Barrierefreiheit: Beim Öffnen setzt der Browser den Fokus auf das erste fokussierbare Element; mit dem Attribut
autofocuslegt man ein anderes Element fest. Beim Schließen geht der Fokus zurück an das zuvor fokussierte Element. Gib dem Dialog eine Beschriftung peraria-labelledby. returnValue: Der Wert bleibt nach dem Schließen erhalten. Setze ihn vor erneutem Öffnen zurück, damit du nicht versehentlich ein altes Ergebnis auswertest.- Kompatibilität:
show(),showModal()undclose()funktionieren in allen modernen Browsern (Baseline 2022).requestClose()undclosedBysind neu und werden noch nicht überall unterstützt. Prüfe sie vorher per Feature-Detection, z. B.'requestClose' in HTMLDialogElement.prototype.