Cambios en NavigationEvent en Chrome 105

Joe Medley
Joe Medley

Chrome 105 presenta dos métodos nuevos en NavigateEvent de la API de Navigation (presentados en la versión 102) para mejorar los métodos que resultaron problemáticos en la práctica. intercept(), que les permite a los desarrolladores controlar el estado después de la navegación, reemplaza a transitionWhile(), que resultó difícil de usar. El método scroll(), que se desplaza hasta un anclaje especificado en la URL, reemplaza a restoreScroll(), que no funciona en todos los tipos de navegación.

En este artículo, explicaremos los problemas de ambos tipos de problemas y cómo los nuevos métodos los solucionan.

El método NavigateEvent.trasitionWhile(), que se introdujo con la API de Navigation en Chrome 102, intercepta la navegación para las transiciones del cliente en apps de una sola página. Su primer argumento es una promesa que le indica al navegador y a otras partes de la aplicación web que finalizó.

Esto no funcionó en la práctica. Considera este patrón de programación común:

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

Esto es funcionalmente equivalente al siguiente código. Hace que una parte de la navegación se ejecute antes de que la API sepa que el desarrollador desea interceptarla.

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

Un ejemplo en el que esto puede alterar una app es en la lógica de restauración del desplazamiento, en la que captura las posiciones de desplazamiento después del cambio del DOM, en lugar de hacerlo antes.

Qué cambió

Para reemplazar transitionWhile(), la especificación actual presenta NavigateEvent.intercept(). El nuevo método toma un controlador además de las propiedades focusReset y scrollRestoration compatibles con transitionWhile(). El nuevo controlador siempre se ejecuta después de que se confirma la navegación y se capturan elementos como las posiciones de desplazamiento, lo que evita los problemas con transitionWhile().

El método transitionWhile() todavía está disponible, pero dejó de estar disponible y se quitará en Chrome 108.

Usa intercept()

NavigateEvent.intercept() tiene las mismas restricciones que transitionWhile(), ya que no se puede llamar en todos los eventos de navegación. Las navegaciones de origen cruzado no se pueden interceptar, como tampoco los recorridos entre documentos. Si lo haces, se arrojará una DOMException del tipo "SecurityError".

Para usar intercept(), solo pasa el controlador personalizado cuando lo llames.

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

Una navegación, como una que va desde la parte superior de la página hasta un ancla (llamarla de /a a /a#id), la controla completamente el navegador, incluso en una app de una sola página. Pero navegar a un ancla en otra "página" (de /a a /b#id), que es sencillo para apps de varias páginas, es más complicado para apps de una sola página. La app debe interceptar la navegación a /b#id usando NavigateEvent.transitionWhile() y, luego, llamar a NavigateEvent.restoreScroll() para mostrar el ancla. Como se mencionó anteriormente, esto es difícil de hacer en este momento.

Qué cambió

En las apps de una sola página, ahora puedes controlar si el navegador controla el desplazamiento a un ancla o si tu código lo hace.

Uso de desplazamiento()

De forma predeterminada, el navegador intentará controlar el desplazamiento automáticamente, una vez que se complete el controlador de intercepción. Si deseas controlar el desplazamiento por tu cuenta, establece scroll en "manual" y, luego, llama a NavigateEvent.scroll() cuando el navegador intente establecer la posición de desplazamiento.

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

El método restoreScroll() todavía está disponible, pero dejó de estar disponible y se quitará en Chrome 108.

Conclusión

Esperamos actualizar pronto nuestro artículo sobre la API de Navigation. Mientras tanto, las especificaciones de esta API contienen mucha información específica para desarrolladores web.

Foto de Tim Gouw en Unsplash