Signatur
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
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);
}
});
});
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);
}
}
});
});
// 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üherenscroll()-Aufruf oder automatisch) oder das Dokument nicht mehr aktiv ist. Rufen Siescroll()daher imhandlerauf, nicht synchron imnavigate-Listener vorintercept(). - Mit dem Standardwert
scroll: "after-transition"scrollt der Browser nach dem Handler automatisch, außerscroll()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
traversehängt auch vonhistory.scrollRestorationab. - 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.