Änderungen an NavigationEvent in Chrome 105

Joe Medley
Joe Medley

In Chrome 105 werden in der NavigateEvent der Navigation API (eingeführt in Version 102) zwei neue Methoden eingeführt, um Methoden zu verbessern, die sich in der Praxis als problematisch erwiesen haben. intercept(), mit dem Entwickler den Status nach der Navigation steuern können, ersetzt transitionWhile(), das sich als schwierig erwiesen hat. Die Methode scroll(), bei der zu einem in der URL angegebenen Anker gescrollt wird, ersetzt restoreScroll(). Sie funktioniert nicht bei allen Navigationstypen.

In diesem Artikel erläutere ich die Probleme beider Methoden und wie sie mit den neuen Methoden behoben werden.

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-Anwendungen ab. Das erste Argument ist ein Versprechen, das dem Browser und anderen Teilen der Webanwendung signalisiert, dass es abgeschlossen ist.

Das hat in der Praxis schlecht funktioniert. Sehen Sie sich dieses gängige Codierungsmuster an:

event.transitionWhile((async () => {
  doSyncStuff();
  await doAsyncStuff();
})());

Funktional entspricht dies dem unten stehenden Code. Sie führt dazu, dass ein Teil der Navigation ausgeführt wird, bevor die API erkennt, dass der Entwickler die Navigation abfangen möchte.

doSyncStuff();
event.transitionWhile((async () => {
  await doAsyncStuff();
})());

Ein Beispiel, das eine App durcheinanderbringen kann, ist die Logik zur Wiederherstellung von Scrolls. Dort werden Scrollpositionen nach der DOM-Änderung statt vorher erfasst.

Was sich geändert hat

Als Ersatz für transitionWhile() wird in der aktuellen Spezifikation NavigateEvent.intercept() eingeführt. Die neue Methode verwendet zusätzlich zu den von transitionWhile() unterstützten Eigenschaften focusReset und scrollRestoration einen Handler. Der neue Handler wird immer ausgeführt, nachdem der Commit der Navigation ausgeführt wurde und Elemente wie Scrollpositionen erfasst wurden. Dadurch werden Probleme mit transitionWhile() vermieden.

Die Methode transitionWhile() ist weiterhin verfügbar, wurde aber eingestellt und wird in Chrome 108 entfernt.

Abfangen()

Für NavigateEvent.intercept() gelten dieselben Einschränkungen wie für transitionWhile(), da sie nicht für alle Navigationsereignisse aufgerufen werden kann. Ursprungsübergreifende Navigationen und dokumentübergreifende Durchläufe können nicht abgefangen werden. Dadurch wird ein DOMException des Typs "SecurityError" ausgegeben.

Wenn Sie intercept() verwenden möchten, übergeben Sie beim Aufruf einfach Ihren benutzerdefinierten Handler.

navigation.addEventListener("navigate", event => {
  event.intercept({
    async handler() {
      doSyncStuff();
      await doAsyncStuff();
    }
  });
});

Eine Navigation, z. B. eine Navigation vom oberen Rand der Seite zu einem Anker (das Verschieben von /a nach /a#id), wird vom Browser komplett ausgeführt, auch in einer App mit nur einer Seite. Die Navigation zu einem Anker auf einer anderen Seite (/a bis /b#id), die für mehrseitige Apps einfach ist, ist jedoch für einseitige Apps komplizierter. Die App muss die Navigation zu /b#id mit NavigateEvent.transitionWhile() abfangen und dann NavigateEvent.restoreScroll() aufrufen, um den Anker sichtbar zu machen. Wie bereits erwähnt, ist dies derzeit schwierig.

Was sich geändert hat

In Single-Page-Anwendungen können Sie jetzt festlegen, ob der Browser das Scrollen zu einem Anker übernimmt oder ob Ihr Code das Scrollen tut.

scroll() verwenden

Standardmäßig versucht der Browser, das Scrollen automatisch durchzuführen, sobald der Intercept-Hander den Vorgang abgeschlossen hat. Wenn du das Scrollen selbst übernehmen möchtest, setze scroll auf "manual" und rufe 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 weiterhin verfügbar, wurde aber eingestellt und wird in Chrome 108 entfernt.

Fazit

Wir hoffen, unseren Artikel über die Navigation API bald aktualisieren zu können. In der Zwischenzeit enthält die Spezifikation dieser API viele Informationen speziell für Webentwickler.

Foto von Tim Gouw auf Unsplash