Start · Sprachen · JavaScript · Referenz · new CloseWatcher()

new CloseWatcher()

Methode

Erstellt ein neues <code>CloseWatcher</code>-Objekt. Es meldet plattformübliche Schließ-Anfragen wie die Esc-Taste oder die Android-Zurück-Geste.

seit JavaScript Chromium 120+ (Chrome, Edge, Opera); in Firefox un Kategorie: webapi

Signatur

new CloseWatcher(options)

Beschreibung

Der Konstruktor CloseWatcher() erzeugt einen Beobachter für Schließ-Anfragen (engl. close requests). Solche Anfragen sind je nach Gerät unterschiedlich: auf dem Desktop meist die Esc-Taste, auf Android die Zurück-Taste bzw. -Geste, außerdem Befehle aus Bedienhilfen wie Screenreadern. Statt all diese Eingaben selbst abzufangen, reagiert man auf die Ereignisse cancel und close des erzeugten Objekts.

Typische Einsatzfälle sind eigene UI-Komponenten, die sich wie ein natives <dialog> oder ein Popover verhalten sollen: Seitenmenüs, Seitenleisten (Drawer), Lightboxen, Kontextmenüs oder Vollbild-Overlays. Jeder neue CloseWatcher kommt auf einen internen Stapel. Eine Schließ-Anfrage trifft immer nur den zuletzt erstellten, noch aktiven Beobachter. Verschachtelte Overlays schließen sich dadurch in der richtigen Reihenfolge.

Über die Option signal übergibt man ein AbortSignal. Wird der zugehörige AbortController abgebrochen, wird der Beobachter zerstört, genau wie bei einem Aufruf von destroy(). Die Aufräumarbeit lässt sich so mit Event-Listenern und fetch-Aufrufen bündeln, die dasselbe Signal verwenden.

Nach dem Erstellen stehen die Methoden requestClose() (löst cancel und danach close aus), close() (löst nur close aus) und destroy() (deaktiviert den Beobachter ohne Ereignis) zur Verfügung.

Parameter

Name Typ Default Beschreibung
$options Object {} Optionales Konfigurationsobjekt.
$options.signal AbortSignal Wird dieses Signal abgebrochen, wird der Beobachter zerstört (wie bei destroy()). Ist das Signal beim Erstellen schon abgebrochen, ist der Beobachter von Anfang an inaktiv.

Rückgabewert

Typ
CloseWatcher
Beschreibung
Ein neues, aktives CloseWatcher-Objekt, das die Ereignisse cancel und close auslöst.

Beispiele

Eigenes Seitenmenü mit Esc bzw. Zurück-Geste schließen

const menu = document.querySelector('#sidebar');
const openButton = document.querySelector('#menu-open');

openButton.addEventListener('click', () => {
  menu.classList.add('open');

  // Beobachter erst beim Öffnen erzeugen
  const watcher = new CloseWatcher();

  watcher.addEventListener('close', () => {
    menu.classList.remove('open');
    console.log('Menü geschlossen');
  });

  // Schließen-Knopf im Menü nutzt denselben Weg
  menu.querySelector('.close').onclick = () => watcher.requestClose();
});
Menü geschlossen (nach Druck auf Esc oder Android-Zurück)

Aufräumen mit AbortSignal

const controller = new AbortController();

const watcher = new CloseWatcher({ signal: controller.signal });
watcher.onclose = () => console.log('close ausgelöst');

// Später, z. B. beim Entfernen der Komponente:
controller.abort();
// Der Beobachter ist jetzt zerstört – Esc löst kein close mehr aus
watcher.requestClose();
console.log('fertig');
fertig

Schließen per cancel-Ereignis verhindern (ungespeicherte Änderungen)

let hasUnsavedChanges = true;
const watcher = new CloseWatcher();

watcher.addEventListener('cancel', (event) => {
  // preventDefault wirkt nur, wenn cancelable === true (Nutzeraktivierung nötig)
  if (hasUnsavedChanges && event.cancelable) {
    event.preventDefault();
    console.log('Bitte zuerst speichern.');
  }
});

watcher.addEventListener('close', () => {
  console.log('Editor geschlossen');
});
Bitte zuerst speichern. (beim ersten Esc nach einer Nutzerinteraktion)

Mit Feature-Erkennung und Rückfall auf keydown

const makeClosable = (onClose) => {
  if ('CloseWatcher' in window) {
    const watcher = new CloseWatcher();
    watcher.onclose = onClose;
    return () => watcher.destroy();
  }
  // Rückfall: nur Esc-Taste
  const handler = (e) => { if (e.key === 'Escape') onClose(); };
  document.addEventListener('keydown', handler);
  return () => document.removeEventListener('keydown', handler);
};

const cleanup = makeClosable(() => console.log('Overlay zu'));

// Wichtig · Fallstricke

  • Browser-Unterstützung: Bisher nur in Chromium-basierten Browsern (ab Version 120). Firefox und Safari unterstützen die API nicht oder nur hinter einem Schalter. Deshalb immer mit 'CloseWatcher' in window prüfen und einen Rückfall (z. B. keydown auf Escape) vorsehen.
  • Schutz vor Missbrauch: Ohne vorherige Nutzerinteraktion angelegte Beobachter werden zu einer Gruppe zusammengefasst. Seiten sollen so die Zurück-Geste nicht „einfangen“ können. Das cancel-Ereignis ist nur nach einer Nutzeraktivierung abbrechbar (event.cancelable). Man sollte sich also nicht darauf verlassen, dass preventDefault() das Schließen verhindert.
  • Einen Beobachter erst erzeugen, wenn die Komponente tatsächlich geöffnet wird, und nach dem Schließen nicht wiederverwenden. Nach close oder destroy() ist er dauerhaft inaktiv. Für das nächste Öffnen einen neuen Beobachter anlegen.
  • Der Konstruktor wirft einen InvalidStateError (DOMException), wenn das zugehörige Dokument nicht vollständig aktiv ist, z. B. in einem entfernten iframe.
  • Für native <dialog>-Elemente und das popover-Attribut ist kein CloseWatcher nötig. Sie nutzen denselben Mechanismus bereits intern.