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 ancla especificada en la URL, reemplaza a restoreScroll()
, que no funciona para todos los tipos de navegación.
En este artículo, explicaré los problemas de ambos y cómo los nuevos métodos los solucionan.
NavigateEvent.transitionWhile()
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 terminó.
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 confirman las operaciones de 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. No se pueden interceptar las navegaciones entre orígenes ni los recorridos entre documentos. Si lo haces, se arrojará un DOMException
del tipo "SecurityError"
.
Para usar intercept()
, simplemente pasa tu controlador personalizado cuando lo llames.
navigation.addEventListener("navigate", event => {
event.intercept({
async handler() {
doSyncStuff();
await doAsyncStuff();
}
});
});
NavigateEvent.scroll()
Una navegación, como una de la parte superior de la página a un ancla (es decir, pasar de /a
a /a#id
), la controla por completo el navegador, incluso en una app de una sola página. Sin embargo, navegar a un ancla en otra "página" (de /a
a /b#id
), que es simple para las apps de varias páginas, es más complicada para las apps de una sola página. La app debe interceptar la navegación a /b#id
con NavigateEvent.transitionWhile()
y, luego, llamar a NavigateEvent.restoreScroll()
para que se muestre el ancla. Como se indicó anteriormente, esto es difícil de hacer en la actualidad.
Qué cambió
En las apps de una sola página, ahora puedes controlar si el navegador controla el desplazamiento a un ancla o si lo hace tu código.
Usa scroll().
De forma predeterminada, el navegador intentará controlar el desplazamiento automáticamente, una vez que se complete el controlador de intercepción. Si quieres 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, la especificación de esta API contiene mucha información específicamente para desarrolladores web.