Chrome 105 presenta dos métodos nuevos en NavigateEvent
de la API de Navigation (presentado en 102) para mejorar los métodos que demostraron ser problemáticos en la práctica. intercept()
, que 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ó bien 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. Esto hace que se ejecute una parte de la navegación antes de que la API sepa que el desarrollador tiene la intención de interceptarla.
doSyncStuff();
event.transitionWhile((async () => {
await doAsyncStuff();
})());
Un ejemplo en el que esto puede afectar una app es en la lógica de restablecimiento del desplazamiento, en la que se capturan posiciones de desplazamiento después del cambio del DOM, en lugar de 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
que admite 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()
aún 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()
El navegador controla por completo una navegación como la de la parte superior de la página a un ancla (llama a esto pasar de /a
a /a#id
), 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 complicado 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 mostrar 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 haya completado el controlador de interceptació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()
aún 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.