Start · Sprachen · JavaScript · Referenz · NavigateEvent.scroll()

NavigateEvent.scroll()

Methode

Löst das Scrollverhalten, das der Browser nach einer abgefangenen Navigation ausführt, manuell und sofort aus, statt auf das Ende des <code>intercept()</code>-Handlers zu warten.

seit JavaScript Chromium 105+ (Chrome, Edge, Opera); in aktuellen Kategorie: webapi

Signatur

NavigateEvent.prototype.scroll()

Beschreibung

Wenn eine Navigation mit NavigateEvent.intercept() abgefangen wird (typisch für Single-Page-Anwendungen), übernimmt der Browser weiterhin das passende Scrollen: Bei push/replace springt er zum Fragment-Anker (#abschnitt) oder an den Seitenanfang, bei traverse (Zurück/Vor) stellt er die gespeicherte Scrollposition wieder her. Standardmäßig (scroll: "after-transition") passiert das erst, wenn das Promise des handler erfüllt ist.

Mit scroll() lösen Sie dieses Verhalten früher aus, etwa sobald der wichtigste Teil der neuen Ansicht gerendert ist, während Nebeninhalte (Kommentare, Empfehlungen) noch nachladen. So springt der Nutzer schon zur richtigen Stelle, ohne auf die gesamte Übergangsphase warten zu müssen.

Setzen Sie in intercept() die Option scroll: "manual", scrollt der Browser überhaupt nicht automatisch. Sie können dann selbst entscheiden, ob und wann scroll() aufgerufen wird, oder komplett eigenes Scrollen (z. B. mit element.scrollIntoView()) umsetzen.

Die Methode ist nur innerhalb eines abgefangenen Navigationsvorgangs sinnvoll und darf pro Navigation nur einmal wirksam aufgerufen werden.

Rückgabewert

Typ
undefined
Beschreibung
Kein Rückgabewert. Das Scrollen wird synchron angestoßen.

Beispiele

Früh scrollen, sobald der Hauptinhalt steht

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() {
      // Hauptinhalt laden und rendern
      const res = await fetch(`/api${url.pathname}`);
      const artikel = await res.json();
      document.querySelector('main').innerHTML = `<h1>${artikel.titel}</h1>`;

      // Jetzt schon scrollen (Anker oder Seitenanfang bzw. alte Position)
      event.scroll();

      // Nebeninhalte dürfen danach in Ruhe nachladen
      const kommentare = await fetch(`/api${url.pathname}/kommentare`).then(r => r.json());
      console.log('Kommentare geladen:', kommentare.length);
    }
  });
});
Kommentare geladen: 12

Manuelles Scrollen: nur bei Vor/Zurück wiederherstellen

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

  event.intercept({
    scroll: 'manual',
    async handler() {
      await renderView(event.destination.url);

      if (event.navigationType === 'traverse') {
        // Gespeicherte Scrollposition wiederherstellen
        event.scroll();
      } else {
        // Bei neuen Seiten eigenes Verhalten: zur Überschrift scrollen
        document.querySelector('h1')?.scrollIntoView({ behavior: 'smooth' });
      }
    }
  });
});

async function renderView(url) {
  const { pathname } = new URL(url);
  document.querySelector('main').innerHTML = `<h1>Ansicht ${pathname}</h1>`;
}

Fehler bei doppeltem Aufruf abfangen

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

  event.intercept({
    async handler() {
      event.scroll();
      try {
        event.scroll(); // zweiter Aufruf ist nicht erlaubt
      } catch (err) {
        console.warn(err.name);
      }
    }
  });
});
InvalidStateError

// Wichtig · Fallstricke

  • InvalidStateError: wird geworfen, wenn das Event nicht per intercept() abgefangen wurde, das Scrollen für diese Navigation bereits stattgefunden hat (durch einen früheren scroll()-Aufruf oder automatisch) oder das Dokument nicht mehr aktiv ist. Rufen Sie scroll() daher im handler auf, nicht synchron im navigate-Listener vor intercept().
  • Mit dem Standardwert scroll: "after-transition" scrollt der Browser nach dem Handler automatisch, außer scroll() wurde bereits aufgerufen. Bei "manual" passiert ohne Ihren Aufruf gar nichts.
  • Rufen Sie scroll() erst auf, wenn das Zielelement (z. B. der Fragment-Anker) im DOM steht. Sonst landet der Nutzer am Seitenanfang statt an der gewünschten Stelle.
  • Die Wiederherstellung der Scrollposition bei traverse hängt auch von history.scrollRestoration ab.
  • Kompatibilität: Die Navigation API gibt es seit Chromium 105; in Firefox und Safari ist sie erst in neueren Versionen verfügbar. Prüfen Sie vorher mit 'navigation' in window, ob die API vorhanden ist, und sehen Sie für ältere Browser eine Lösung mit der History API vor.