Zmiany w nawigacji Event w Chrome 105

Joe Medley
Joe Medley

Chrome 105 wprowadza 2 nowe metody w interfejsie NavigateEvent interfejsu API nawigacji (wprowadzonego w wersji 102), aby ulepszyć metody, które okazały się problematyczne w praktyce. intercept(), który pozwala deweloperom kontrolować stan po nawigacji, zastępuje transitionWhile(), który okazał się trudny w użyciu. Metoda scroll(), która przewija do zakotwiczenia określonego w adresie URL, zastępuje metodę restoreScroll(), która nie działa w przypadku niektórych typów nawigacji.

W tym artykule opisuję problemy związane z tymi metodami i sposoby ich rozwiązania.

Metoda NavigateEvent.trasitionWhile(), wprowadzona w ramach interfejsu Navigation API w wersji Chrome 102, przechwytuje nawigację w przypadku przejść po stronie klienta w aplikacjach jednostronicowych. Pierwszym argumentem jest obietnica, która sygnalizuje przeglądarce i innym częściom aplikacji internetowej, że jest gotowa.

W praktyce nie działało to dobrze. Weź pod uwagę ten typowy schemat kodowania:

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

Pod względem funkcjonalności jest to równoważne z podanym niżej kodem. Powoduje to, że część nawigacji jest wykonywana, zanim interfejs API dowie się, że deweloper chce ją przechwycić.

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

Przykładem, w którym może to spowodować problemy z aplikacją, jest logika przywracania przewijania, która rejestruje pozycje przewijania po zmianie DOM, a nie przed nią.

Co się zmieniło

Aby zastąpić transitionWhile(), obecna specyfikacja wprowadza NavigateEvent.intercept(). Nowa metoda przyjmuje obiekt obsługi oprócz właściwości focusReset i scrollRestoration obsługiwanych przez transitionWhile(). Nowy handler zawsze działa po zatwierdzeniu nawigacji, a takie rzeczy jak pozycje przewijania zostały już przechwycone, co pozwala uniknąć problemów z transitionWhile().

Metoda transitionWhile() jest nadal dostępna, ale została wycofana i zostanie usunięta w Chrome 108.

Funkcja intercept()

Zdarzenie NavigateEvent.intercept() podlega tym samym ograniczeniom co zdarzenie transitionWhile(), ponieważ nie może być wywoływane w przypadku wszystkich zdarzeń nawigacyjnych. Nie można przechwycić nawigacji między domenami ani przechodzenia między dokumentami. Spowoduje to wygenerowanie obiektu DOMException typu "SecurityError".

Aby użyć intercept(), po prostu prześlij niestandardowy moduł obsługi podczas wywołania.

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

Nawigacja, np. z góry strony do kotwicy (czyli przejście z /a do /a#id), jest obsługiwana całkowicie przez przeglądarkę, nawet w przypadku aplikacji jednostronicowych. Natomiast przejście do kotwicy na innej „stronie” (z /a do /b#id), które jest proste w przypadku aplikacji wielostronicowych, jest bardziej skomplikowane w przypadku aplikacji jednostronicowych. Aplikacja musi przechwycić nawigację do /b#id za pomocą NavigateEvent.transitionWhile(), a potem wywołać NavigateEvent.restoreScroll(), aby wyświetlić kotwicę. Jak już wspomnieliśmy, obecnie jest to trudne.

Co się zmieniło

W aplikacjach jednostronicowych możesz teraz określić, czy przewijanie do kotwicy ma obsługiwać przeglądarka, czy kod.

Używanie scroll()

Domyślnie przeglądarka będzie automatycznie obsługiwać przewijanie po wykonaniu przechwytu. Jeśli chcesz samodzielnie obsługiwać przewijanie, ustaw scroll na "manual", a następnie wywołaj NavigateEvent.scroll(), gdy przeglądarka ma spróbować ustawić pozycję przewijania.

navigation.addEventListener("manual", event => {
  scroll: "manual",
  event.intercept({
    async handler() {
      doSyncStuff();
      // Handle scrolling earlier than by default:
      event.scroll();
      await doAsyncStuff();
    }
  });
});

Metoda restoreScroll() jest nadal dostępna, ale została wycofana i zostanie usunięta w Chrome 108.

Podsumowanie

Mamy nadzieję, że wkrótce zaktualizujemy nasz artykuł o interfejsie Navigation API. Tymczasem specyfikacja tego interfejsu API zawiera wiele informacji przeznaczonych specjalnie dla programistów internetowych.

Zdjęcie autorstwa Tim GouwUnsplash