In Chrome 105 werden zwei neue Methoden für die NavigateEvent
der Navigation API (in Version 102 eingeführt) eingeführt, um Methoden zu verbessern, die sich in der Praxis als problematisch erwiesen haben. intercept()
ersetzt transitionWhile()
, das sich als schwierig in der Anwendung erwiesen hat. Mit intercept()
können Entwickler den Status nach der Navigation steuern. Die Methode scroll()
, mit der zu einem in der URL angegebenen Anker gescrollt wird, ersetzt restoreScroll()
, die nicht für alle Navigationstypen funktioniert.
In diesem Artikel erkläre ich die Probleme mit beiden und wie diese mit den neuen Methoden behoben werden.
NavigateEvent.transitionWhile()
Die Methode NavigateEvent.trasitionWhile()
, die mit der Navigation API in Chrome 102 eingeführt wurde, fängt die Navigation für clientseitige Übergänge in Single-Page-Apps ab. Das erste Argument ist ein Versprechen, das dem Browser und anderen Teilen der Webanwendung signalisiert, dass die Ausführung abgeschlossen ist.
Das hat in der Praxis nicht gut funktioniert. Betrachten wir dieses gängige Codierungsmuster:
event.transitionWhile((async () => {
doSyncStuff();
await doAsyncStuff();
})());
Funktionell entspricht dies dem Code unten. Dadurch wird ein Teil der Navigation ausgeführt, bevor die API weiß, dass der Entwickler die Navigation abfangen möchte.
doSyncStuff();
event.transitionWhile((async () => {
await doAsyncStuff();
})());
Ein Beispiel dafür, wie sich das auf eine App auswirken kann, ist die Logik zur Wiederherstellung des Scrollens, bei der die Scrollpositionen nach der DOM-Änderung erfasst werden, anstatt davor.
Änderungen
Anstelle von transitionWhile()
wird in der aktuellen Spezifikation NavigateEvent.intercept()
verwendet. Die neue Methode nimmt zusätzlich zu den von transitionWhile()
unterstützten focusReset
- und scrollRestoration
-Attributen einen Handler an. Der neue Handler wird immer nach dem Navigationscommit ausgeführt und Dinge wie Scrollpositionen wurden erfasst, sodass die Probleme mit transitionWhile()
vermieden werden.
Die Methode transitionWhile()
ist zwar noch verfügbar, wurde aber eingestellt und wird in Chrome 108 entfernt.
intercept() verwenden
Für NavigateEvent.intercept()
gelten dieselben Einschränkungen wie für transitionWhile()
, d. h., es kann nicht bei allen Navigationsereignissen aufgerufen werden. Navigationen zwischen verschiedenen Ursprüngen und ‑dokumenten können nicht abgefangen werden. Dadurch wird eine DOMException
vom Typ "SecurityError"
geworfen.
Wenn du intercept()
verwenden möchtest, musst du beim Aufrufen einfach deinen benutzerdefinierten Handler übergeben.
navigation.addEventListener("navigate", event => {
event.intercept({
async handler() {
doSyncStuff();
await doAsyncStuff();
}
});
});
NavigateEvent.scroll()
Die Navigation von oben auf der Seite zu einem Anker (z. B. von /a
zu /a#id
) wird auch in einer App mit einer einzelnen Seite vollständig vom Browser verarbeitet. Das Aufrufen eines Ankers auf einer anderen „Seite“ (/a
zu /b#id
), was in Apps mit mehreren Seiten einfach ist, ist in Apps mit einer einzelnen Seite komplizierter. Die App muss die Navigation zu /b#id
mit NavigateEvent.transitionWhile()
abfangen und dann NavigateEvent.restoreScroll()
aufrufen, um den Anker einzublenden. Wie bereits erwähnt, ist das derzeit schwierig.
Änderungen
In Single-Page-Apps können Sie jetzt festlegen, ob das Scrollen zu einem Anker vom Browser oder von Ihrem Code gesteuert wird.
scroll() verwenden
Standardmäßig versucht der Browser, das Scrollen automatisch zu verarbeiten, sobald der Intercept-Handler ausgeführt wurde. Wenn Sie das Scrollen selbst steuern möchten, legen Sie scroll
auf "manual"
fest und rufen Sie dann NavigateEvent.scroll()
auf, wenn der Browser versuchen soll, die Scrollposition festzulegen.
navigation.addEventListener("manual", event => {
scroll: "manual",
event.intercept({
async handler() {
doSyncStuff();
// Handle scrolling earlier than by default:
event.scroll();
await doAsyncStuff();
}
});
});
Die Methode restoreScroll()
ist zwar noch verfügbar, wurde aber eingestellt und wird in Chrome 108 entfernt.
Fazit
Wir werden unseren Artikel zur Navigation API bald aktualisieren. In der Zwischenzeit enthält die Spezifikation für diese API viele Informationen speziell für Webentwickler.