Start · Sprachen · JavaScript · Referenz · NavigateEvent.signal

NavigateEvent.signal

Eigenschaft

Schreibgeschütztes <code>AbortSignal</code>, das ausgelöst wird, sobald die abgefangene Navigation abgebrochen wird – etwa durch die Stopp-Taste oder eine neue Navigation.

seit JavaScript Navigation API: Chromium 102+, Firefox 147+, Safar Kategorie: webapi

Signatur

NavigateEvent.signal

Beschreibung

Die Eigenschaft signal eines NavigateEvent liefert ein AbortSignal, das an die aktuelle Navigation gebunden ist. Es wird abgebrochen (aborted === true), wenn die Navigation nicht mehr fortgesetzt werden soll, z. B. weil der Nutzer im Browser auf „Stopp“ klickt, eine andere Navigation startet (neuer Link-Klick, navigation.navigate(), Zurück-Taste) oder window.stop() aufgerufen wird.

Gedacht ist das Signal vor allem für Single-Page-Anwendungen, die Navigationen mit event.intercept() abfangen und im handler asynchron Daten laden. Reicht man event.signal an fetch() oder andere abbrechbare APIs weiter, werden veraltete Anfragen automatisch abgebrochen und es entstehen keine Wettlaufsituationen, bei denen eine langsame alte Antwort die neue Seite überschreibt.

Zusätzlich kann man mit signal.addEventListener("abort", …) oder signal.throwIfAborted() eigene Aufräumarbeiten erledigen, etwa Ladeanzeigen ausblenden, Animationen stoppen oder lange Berechnungsschleifen beenden. Über signal.reason lässt sich der Grund des Abbruchs (in der Regel eine DOMException mit Namen "AbortError") auslesen.

Rückgabewert

Typ
AbortSignal
Beschreibung
Ein AbortSignal, das abgebrochen wird, sobald die zugehörige Navigation abgebrochen wird. Die Eigenschaft ist schreibgeschützt.

Beispiele

Signal an fetch() im Intercept-Handler weitergeben

navigation.addEventListener("navigate", (event) => {
  if (!event.canIntercept || event.hashChange || event.downloadRequest) return;

  const url = new URL(event.destination.url);
  if (!url.pathname.startsWith("/artikel/")) return;

  event.intercept({
    async handler() {
      // Bricht die Anfrage automatisch ab, wenn der Nutzer weiternavigiert
      const response = await fetch(`/api${url.pathname}`, {
        signal: event.signal,
      });
      const artikel = await response.json();
      document.querySelector("main").textContent = artikel.titel;
    },
  });
});

Aufräumen beim Abbruch über das abort-Ereignis

navigation.addEventListener("navigate", (event) => {
  if (!event.canIntercept) return;

  const spinner = document.querySelector("#lade-anzeige");

  event.intercept({
    async handler() {
      spinner.hidden = false;

      event.signal.addEventListener("abort", () => {
        spinner.hidden = true;
        console.log("Navigation abgebrochen:", event.signal.reason?.name);
      }, { once: true });

      await new Promise((resolve) => setTimeout(resolve, 3000));
      spinner.hidden = true;
    },
  });
});

// Klickt der Nutzer während der 3 Sekunden auf „Stopp“:
Navigation abgebrochen: AbortError

Lange Verarbeitung mit throwIfAborted() abbrechen

const renderListe = async (eintraege, signal) => {
  const liste = document.querySelector("#liste");
  liste.replaceChildren();
  for (const eintrag of eintraege) {
    signal.throwIfAborted(); // wirft AbortError, falls abgebrochen
    const li = document.createElement("li");
    li.textContent = eintrag;
    liste.append(li);
    await new Promise(requestAnimationFrame); // UI nicht blockieren
  }
};

navigation.addEventListener("navigate", (event) => {
  if (!event.canIntercept) return;
  event.intercept({
    handler: async () => {
      const daten = Array.from({ length: 500 }, (_, i) => `Eintrag ${i + 1}`);
      try {
        await renderListe(daten, event.signal);
      } catch (err) {
        if (err.name === "AbortError") console.log("Rendern gestoppt");
        else throw err;
      }
    },
  });
});
Rendern gestoppt

// Wichtig · Fallstricke

  • Browser-Kompatibilität: Die Navigation API ist lange nur in Chromium-Browsern (Chrome, Edge, Opera ab Version 102) verfügbar gewesen; in Firefox und Safari kam sie erst später hinzu. Vorher per if ("navigation" in window) prüfen und einen Fallback (z. B. History API) vorsehen.
  • Das Signal wird nur für die jeweilige Navigation ausgelöst. Nach erfolgreichem Abschluss wird es nicht abgebrochen – ein abort-Listener läuft also nur bei echtem Abbruch.
  • Wird ein Handler abgebrochen und reicht man das Signal an fetch() weiter, verwirft der Browser das Promise mit einem AbortError. Wer den Fehler abfängt, sollte AbortError von echten Netzwerkfehlern unterscheiden und nicht als Fehlermeldung anzeigen.
  • Ohne event.intercept() ist das Signal kaum nützlich, da die Navigation dann ohnehin normal (mit Seitenwechsel) abläuft.
  • Soll bei Abbruch zusätzlich ein Zeitlimit gelten, lassen sich Signale mit AbortSignal.any([event.signal, AbortSignal.timeout(5000)]) kombinieren (neuere Browser).