Änderungen an NavigationEvent in Chrome 105

Joe Medley
Joe Medley

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.

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.

In der Praxis funktionierte das jedoch nicht gut. Sehen Sie sich dieses gängige Codierungsmuster an:

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

Funktional entspricht dies dem unten stehenden Code. 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 Eigenschaften focusReset und scrollRestoration einen Handler an. Der neue Handler wird immer nach dem Navigationscommit ausgeführt und Dinge wie Scrollpositionen werden 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.

duct() 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();
    }
  });
});

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 dies 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 weiterhin 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 dieser API viele Informationen speziell für Webentwickler.

Foto von Tim Gouw auf Unsplash