Änderungen an NavigationEvent in Chrome 105

Joe Medley
Joe Medley

In Chrome 105 werden in 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 Zustand nach der Navigation steuern können, ersetzt transitionWhile(), da sich die Verwendung als schwierig erwiesen hat. Die Methode scroll(), die zu einem in der URL angegebenen Anker scrollt, ersetzt restoreScroll(), der nicht bei allen Navigationsarten funktioniert.

In diesem Artikel erkläre ich die Probleme und wie sie mit den neuen Methoden behoben werden.

Die NavigateEvent.trasitionWhile()-Methode, 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, dass dem Browser und anderen Teilen der Webanwendung signalisiert wird, dass der Vorgang abgeschlossen ist.

Dies hat in der Praxis schlecht funktioniert. Betrachten Sie dieses gängige Codierungsmuster:

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

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

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

Dies kann beispielsweise in der Logik zur Wiederherstellung von Scrollvorgängen dazu führen, dass die Scrollpositionen nach der DOM-Änderung und nicht danach erfasst werden.

Was sich geändert hat

Als Ersatz für transitionWhile() wurde NavigateEvent.intercept() mit der aktuellen Spezifikation 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 nach den Commits der Navigation ausgeführt und Dinge wie Scrollpositionen wurden erfasst, um Probleme mit transitionWhile() zu vermeiden.

Die Methode transitionWhile() ist weiterhin 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(), da sie nicht für alle Navigationsereignisse aufgerufen werden kann. Ursprungsübergreifende Navigationen können nicht abgefangen und dokumentübergreifende Durchläufe nicht abgefangen werden. Dadurch wird ein DOMException des Typs "SecurityError" ausgegeben.

Um intercept() zu verwenden, übergeben Sie einfach Ihren benutzerdefinierten Handler beim Aufruf.

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

Eine Navigation wie die Navigation vom oberen Rand der Seite zu einem Anker (z. B. von /a zu /a#id) wird vom Browser vollständig ausgeführt, selbst in einer einseitigen App. Das Aufrufen eines Ankers auf einer anderen Seite (/a zu /b#id), was für mehrseitige Apps einfacher ist, ist für einseitige Apps jedoch 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

Bei einseitigen Apps können Sie jetzt festlegen, ob der Browser das Scrollen zu einem Anker übernimmt oder ob das in Ihrem Code der Fall ist.

scroll() verwenden

Standardmäßig versucht der Browser, das Scrollen automatisch auszuführen, sobald der Intercept Hander die Anforderungen erfüllt. Wenn Sie das Scrollen selbst verwalten möchten, setzen Sie scroll auf "manual" 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 hoffen, unseren Artikel über die Navigations-API bald aktualisieren zu können. In der Zwischenzeit enthält die Spezifikation für diese API viele Informationen speziell für Webentwickler.

Foto von Tim Gouw auf Unsplash