View Transitions
Las View Transitions son transiciones animadas entre diferentes vistas de un sitio web. Son una elección de diseño popular para preservar la continuidad visual cuando los usuarios navegan entre estados o vistas de una aplicación.
La compatibilidad de Astro con las transiciones de vista y el enrutamiento del lado del cliente está impulsada por la API del navegador View Transitions, y también incluye:
- Algunas opciones de animación integradas, como
fade
,slide
ynone
. - Soporte para animaciones de navegación hacia adelante y hacia atrás.
- La capacidad de personalizar completamente todos los aspectos de la animación de transición y crear tus propias animaciones.
- La opción de impedir la navegación del lado del cliente para enlaces que no sean de página.
- Control sobre el comportamiento de respaldo para navegadores que aún no admiten las API de View Transitions.
- Soporte automático para
prefers-reduced-motion
.
Por defecto, cada página utilizará la navegación normal del navegador, ocupando toda la página. Debes optar por ver las view transitions y puedes usarlas por página o en todo el sitio.
Diferencias entre las transiciones de vista nativas del navegador y el <ClientRouter />
de Astro
Sección titulada «Diferencias entre las transiciones de vista nativas del navegador y el <ClientRouter /> de Astro»Las transiciones de vista nativas del navegador entre documentos se pueden usar en Astro para animar la navegación entre documentos en una aplicación de múltiples páginas (MPA), ofreciendo a menudo una experiencia similar al enrutamiento del lado del cliente en aplicaciones de una sola página (SPA). No modifican la funcionalidad principal de una aplicación de múltiples páginas, ni afectan los scripts existentes ni añaden JavaScript adicional a la carga de tu página. Simplemente añaden animaciones.
Para funciones mejoradas de enrutamiento del lado del cliente y transiciones de vista que aún no están totalmente soportadas por la API de transiciones de vista, Astro ofrece un componente integrado y liviano que permite el enrutamiento del lado del cliente y convierte tu aplicación de múltiples páginas en una aplicación de una sola página con animaciones fluidas al navegar.
Esto ofrece algunos beneficios, como el estado compartido entre páginas y elementos persistentes, pero también algunas desventajas, como la necesidad de reinicializar manualmente scripts o estado después de la navegación.
Agregando el componente integrado <ClientRouter />
de Astro:
- Interceptara la navegación entre páginas y te da un control considerable sobre este proceso.
- Amplía y mejora algunas características de la API de navegación/transiciones de vista.
- Te permite configurar estrategias de respaldo para cuando el soporte nativo del navegador sea limitado.
Sin embargo, a medida que las APIs del navegador y los estándares web evolucionan, usar el <ClientRouter />
de Astro para esta funcionalidad adicional será cada vez menos necesario. Recomendamos mantenerte al tanto del estado actual de las APIs del navegador para que puedas decidir si aún necesitas el enrutamiento del lado del cliente de Astro según las funciones específicas que utilices.
Claro, aquí tienes la traducción al español:
Activar transiciones de vista (modo SPA)
Sección titulada «Activar transiciones de vista (modo SPA)»Importa y agrega el componente <ClientRouter />
en tu <head>
común o en un componente de layout compartido. Astro creará animaciones de página predeterminadas basadas en las similitudes entre la página anterior y la nueva, y también proporcionará un comportamiento de respaldo para los navegadores que no sean compatibles.
El siguiente ejemplo muestra cómo agregar las animaciones de navegación predeterminadas de Astro en todo el sitio, incluyendo la opción de control de respaldo para navegadores no compatibles, importando y añadiendo este componente a un componente Astro llamado <CommonHead />
:
---import { ClientRouter } from "astro:transitions";---<link rel="icon" type="image/svg+xml" href="/favicon.svg" /><meta name="generator" content={Astro.generator} />
<!-- Meta etiquetas principales --><title>{title}</title><meta name="title" content={title} /><meta name="description" content={description} />
<ClientRouter />
¡No se necesita ninguna otra configuración para habilitar la navegación del lado del cliente predeterminada de Astro!
Usa directivas de transición o anula la navegación del lado del cliente en elementos individuales para un control más detallado.
Directivas de transición
Sección titulada «Directivas de transición»Astro asignará automáticamente a los elementos encontrados tanto en la página antigua como en la nueva un view-transition-name
compartido y único. Esta pareja de elementos coincidentes es inferida por el tipo de elemento y su ubicación en el DOM.
Utiliza las directivas opcionales transition:*
en los elementos de la página dentro de tus componentes .astro
para un control más fino sobre la animación de transición de la página durante la navegación.
transition:name
: Te permite anular la coincidencia de elementos predeterminada de Astro para la animación del contenido antiguo/nuevo y especificar un nombre de transición para asociar un par de elementos DOM.transition:animate
: Te permite modificar la animación predeterminada de Astro mientras reemplaza el elemento antiguo por el nuevo especificando un tipo de animación. Utiliza las directivas de animación integradas de Astro o crea animaciones de transición personalizadas.transition: persist
: Te permite anular el reemplazo predeterminado de los elementos antiguos por los nuevos de Astro y, en su lugar, persistir los componentes y elementos HTML al navegar a otra página.
Nombrando una transición
Sección titulada «Nombrando una transición»En algunos casos, es posible que desees o necesites identificar los elementos de transición de vista correspondientes tú mismo. Puedes especificar un nombre para un par de elementos utilizando la directiva transition:name
.
<aside transition:name="hero">
<aside transition:name="hero">
Ten en cuenta que el valor proporcionado transition:name
solo se puede utilizar una vez en cada página. Establece esto manualmente solo cuando Astro no pueda inferir un nombre adecuado por sí mismo, o para un control más fino sobre los elementos coincidentes.
Manteniendo el estado
Sección titulada «Manteniendo el estado»
Agregado en:
astro@2.10.0
Puedes persistir componentes y elementos HTML (en lugar de reemplazarlos) a través de las navegaciones de página utilizando la directiva transition:persist
.
Por ejemplo, el siguiente <video>
continuará reproduciéndose a medida que navegas a otra página que contiene el mismo elemento de video. Esto funciona tanto para la navegación hacia adelante como hacia atrás.
<video controls="" autoplay="" transition:persist> <source src="https://ia804502.us.archive.org/33/items/GoldenGa1939_3/GoldenGa1939_3_512kb.mp4" type="video/mp4"></video>
También puedes colocar la directiva en una isla de Astro (un componente de framework UI con una directiva client:
). Si ese componente existe en la siguiente página, la isla de la página antigua con su estado actual continuará mostrándose, en lugar de reemplazarla con la isla de la nueva página.
En el siguiente ejemplo, el estado interno del componente del recuento no se restablecerá cuando se navegue hacia adelante y hacia atrás por páginas que contengan el componente <Counter />
con el atributo transition:persist
.
<Counter client:load transition:persist initialCount={5} />
No todo el estado puede preservarse de esta forma. El reinicio de animaciones CSS y la recarga de iframes no se pueden evitar durante las transiciones de vista, incluso al usar transition:persist
.
También puedes identificar manualmente los elementos correspondientes si la isla/elemento está en un componente diferente entre las dos páginas.
<video controls muted autoplay transition:name="media-player" transition:persist/>
<MyVideo controls muted autoplay transition:name="media-player" transition:persist/>
Una alternativa práctica, transition:persist
puede tomar un nombre de transición como valor.
<video controls muted autoplay transition:persist="media-player">
transition:persist-props
Sección titulada «transition:persist-props»
Agregado en:
astro@4.5.0
Esto te permite controlar si laprops de una isla deben persistir o no tras la navegación.
Por defecto, cuando se añade transition:persist
a una isla, el estado se mantiene durante la navegación, pero el componente se vuelve a renderizar con nuevos props. Esto es útil, por ejemplo, cuando un componente recibe props específicos de la página, como el title
de la página actual.
Puede anular este comportamiento con transition:persist-props
. Al añadir esta directiva se conservarán los accesorios existentes de una isla (no se volverá a renderizar con nuevos valores) además de mantener su estado existente.
Directivas de animación integradas
Sección titulada «Directivas de animación integradas»Astro viene con algunas animaciones integradas para anular la transición fade
predeterminada. Agrega la directiva transition:animate
a elementos individuales para personalizar el comportamiento de transiciones específicas.
fade
(por defecto): Una animación de fundido cruzado opinionada. El contenido antiguo se desvanece y el nuevo contenido se desvanece al aparecer.initial
: Optar por no usar la animación de fundido cruzado opinionada de Astro y en su lugar utilizar el estilo predeterminado del navegador.slide
: Una animación donde el contenido antiguo se desliza hacia la izquierda y el nuevo contenido se desliza desde la derecha. En la navegación hacia atrás, las animaciones son opuestas.none
: Desactiva las animaciones predeterminadas del navegador. Úsalo en el elemento<html>
de una página para desactivar el fade predeterminado para cada elemento en la página.
Combina directivas para tener un control total sobre la animación de tu página. Establece un valor predeterminado para la página en el elemento <html>
, y anúlalo en los elementos individuales que desees.
El siguiente ejemplo produce una animación de deslizamiento para el contenido del cuerpo, al mismo tiempo que desactiva la animación de fundido predeterminada del navegador para el resto de la página:
---import CommonHead from '../components/CommonHead.astro';---
<html transition:animate="none"> <head> <CommonHead /> </head> <body> <header> ... </header> <!-- Anula la configuración predeterminada de tu página en un solo elemento --> <main transition:animate="slide"> ... </main> </body></html>
Personalizando Animaciones
Sección titulada «Personalizando Animaciones»Puedes personalizar todos los aspectos de una transición utilizando las propiedades de animación de CSS.
Para personalizar una animación incorporada, primero importa la animación desde astro:transitions
, y luego proporciona opciones de personalización.
El ejemplo a continuación personaliza la duración de la animación incorporada fade
:
---import { fade } from 'astro:transitions';---
<header transition:animate={fade({ duration: '0.4s' })}>
También puedes definir tus propias animaciones para usar con transition:animate
, definiendo tanto el comportamiento hacia adelante como hacia atrás, así como las páginas nuevas y antiguas, de acuerdo con los siguientes tipos:
export interface TransitionAnimation { name: string; // El nombre del keyframe delay?: number | string; duration?: number | string; easing?: string; fillMode?: string; direction?: string;}
export interface TransitionAnimationPair { old: TransitionAnimation | TransitionAnimation[]; new: TransitionAnimation | TransitionAnimation[];}
export interface TransitionDirectionalAnimations { forwards: TransitionAnimationPair; backwards: TransitionAnimationPair;}
El siguiente ejemplo muestra todas las propiedades necesarias para definir una animación personalizada bump
dentro de una etiqueta <style is:global>
en tu archivo de layout raíz:
---import { ClientRouter } from "astro:transitions";---<html lang="en"> <head> <ClientRouter /> </head> <body> <slot /> </body></html>
<style is:global> @keyframes bump { 0% { opacity: 0; transform: scale(1) translateX(200px); } 50% { opacity: 0.5; transform: scale(1.1); } 100% { opacity: 1; transform: scale(1) translateX(0); } }</style>
El comportamiento de la animación debe definirse en el frontmatter de cada componente que utilice la animación:
---const anim = { old: { name: "bump", duration: "0.5s", easing: "ease-in", direction: "reverse", }, new: { name: "bump", duration: "0.5s", easing: "ease-in-out", },};
const customTransition = { forwards: anim, backwards: anim,};---<header transition:animate={customTransition}> ... </header>
Tienes una gran flexibilidad al definir animaciones personalizadas. Para lograr el resultado que deseas, podrías considerar combinaciones poco comunes, como usar objetos distintos para las transiciones hacia adelante y hacia atrás, o proporcionar animaciones de keyframe separadas para el estado anterior y el nuevo.
Controlar el enrutador
Sección titulada «Controlar el enrutador»El enrutador <ViewTransitions />
maneja la navegación escuchando:
- Los clics en elementos
<a>
. - Eventos de navegación hacia atrás y hacia adelante.
Las siguientes opciones te permiten controlar aún más cuándo ocurre la navegación dentro del enrutador:
data-astro-reload
: un atributo de la etiqueta<a>
para forzar una navegación de página completa.data-astro-history="auto | push | replace"
: un atributo de la etiqueta<a>
para controlar el historial del navegador.navigate(href, options)
: un método disponible para cualquier script o componente cliente para desencadenar la navegación.
Previniendo la navegación del lado del cliente
Sección titulada «Previniendo la navegación del lado del cliente»Existen casos en los que no se puede navegar a través del enrutamiento del lado del cliente ya que ambas páginas involucradas deben utilizar el enrutador <ViewTransitions />
para evitar una recarga de página completa. También puede que no desees la navegación del lado del cliente en cada cambio de navegación y prefieras una navegación de página tradicional en rutas selectas en su lugar.
Puedes optar por no utilizar la navegación del lado del cliente de manera selectiva para cada enlace añadiendo el atributo data-astro-reload
a cualquier etiqueta <a>
o <form>
. Este atributo anulará cualquier componente <ViewTransitions />
existente y, en su lugar, provocará una recarga del navegador durante la navegación.
El siguiente ejemplo muestra cómo evitar la navegación del lado del cliente al navegar a un artículo desde la página de inicio únicamente. Esto aún te permite tener animaciones en elementos compartidos, como una imagen destacada, al navegar a la misma página desde una página de listado de artículos:
<a href="/articles/emperor-penguins" data-astro-reload>
<a href="/articles/emperor-penguins">
Los enlaces con el atributo data-astro-reload
serán ignorados por el enrutador y se producirá una navegación de página completa.
Desencadenar la navegación
Sección titulada «Desencadenar la navegación»También puedes desencadenar la navegación del lado del cliente a través de eventos que normalmente no son escuchados por el enrutador <ViewTransitions />
utilizando navigate
. Esta función del módulo astro:transitions/client
se puede utilizar en scripts y en componentes del framework que se hidratan con una directiva de cliente.
El siguiente ejemplo muestra un componente de Astro que lleva al visitante a otra página que selecciona desde un menú:
<script> import { navigate } from 'astro:transitions/client'; // Navega a la opción seleccionada automáticamente. document.querySelector('select').onchange = (ev) => { let href = ev.target.value; navigate(href); };</script><select> <option value="/play">Jugar</option> <option value="/blog">Blog</option> <option value="/about">Acerca de</option> <option value="/contact">Contacto</option></select>
---import Form from "../components/Form.astro";import { ViewTransitions } from "astro:transitions";---<html> <head> <ViewTransitions /> </head> <body> <Form /> </body></html>
El siguiente ejemplo implementa lo mismo usando navigate()
en un componente <Form />
de React:
import { navigate } from "astro:transitions/client";
export default function Form() { return ( <select onChange={(e) => navigate(e.target.value)}> <option value="/play">Jugar</option> <option value="/blog">Blog</option> <option value="/about">Acerca de</option> <option value="/contact">Contacto</option> </select> );}
El componente <Form />
puede ser renderizado en una página de Astro que utiliza el enrutador <ViewTransitions />
, con una directiva del cliente:
---import Form from "../components/Form.jsx";import { ViewTransitions } from "astro:transitions";---<html> <head> <ViewTransitions /> </head> <body> <Form client:load /> </body></html>
El método navigate
toma los siguientes argumentos:
href
(obligatorio) - La nueva página a la que se va a navegar.options
- Un objeto opcional con las siguientes propiedades:history
:'push'
|'replace'
|'auto'
'push'
: el enrutador utilizaráhistory.pushState
para crear una nueva entrada en el historial del navegador.'replace'
: el enrutador utilizaráhistory.replaceState
para actualizar la URL sin agregar una nueva entrada en la navegación.'auto'
(por defecto): el enrutador intentará utilizarhistory.pushState
, pero si la URL no es una que se pueda transicionar, la URL actual permanecerá sin cambios en el historial del navegador.
formData
: Un objeto FormData para solicitudesPOST
.
Para navegar hacia atrás y hacia delante por el historial del navegador, puedes combinar navigate()
con las funciones integradas history.back()
, history.forward()
e history.go()
del navegador. Si navigate()
es llamado durante la renderización del lado del servidor de tu componente, no tendrá efecto alguno.
Reemplazar entradas en el historial del navegador
Sección titulada «Reemplazar entradas en el historial del navegador»Normalmente, cada vez que navegas, se crea una nueva entrada en el historial del navegador. Esto permite la navegación entre páginas utilizando los botones atrás
y adelante
del navegador.
El enrutador <ViewTransitions />
te permite sobrescribir las entradas del historial al agregar el atributo data-astro-history
a cualquier etiqueta <a>
individual.
El atributo data-astro-history
puede establecerse en los mismos tres valores que la opción history
de la función navigate()
:
data-astro-history
: 'push'
| 'replace'
| 'auto'
'push'
: el enrutador utilizaráhistory.pushState
para crear una nueva entrada en el historial del navegador.'replace'
: el enrutador utilizaráhistory.replaceState
para actualizar la URL sin agregar una nueva entrada en la navegación.'auto'
(por defecto): el enrutador intentará utilizarhistory.pushState
, pero si la URL no se puede transicionar, la URL actual se mantendrá sin cambios en el historial del navegador.
El siguiente ejemplo navega a la página /main
, pero no agrega una nueva entrada al historial de navegación. En cambio, reutiliza la entrada actual en el historial (/confirmation
) y la sobrescribe.
<a href="/main" data-astro-history="replace">
Esto tiene el efecto de que si retrocedes desde la página /main
, el navegador no mostrará la página /confirmation
, sino la página anterior a ella.
Transiciones con formularios
Sección titulada «Transiciones con formularios»
Agregado en:
astro@4.0.0
El enrutador <ViewTransitions />
activará transiciones en la página desde elementos <form>
, admitiendo tanto peticiones GET
como POST
.
Por defecto, Astro envía los datos de tu formulario como multipart/form-data
cuando el atributo method
está configurado como POST
. Si deseas que coincida con el comportamiento predeterminado de los navegadores web, utiliza el atributo enctype
para enviar tus datos codificados como application/x-www-form-urlencoded
:
<form action="/contact" method="POST" enctype="application/x-www-form-urlencoded">
Puedes optar por excluir las transiciones del enrutador en formularios individuales mediante el atributo data-astro-reload
:
<form action="/contact" data-astro-reload>
Control de respaldo
Sección titulada «Control de respaldo»El enrutador <ViewTransitions />
funciona mejor en navegadores que admiten las View Transitions (p.ej. navegadores basados en Chromium), pero también incluye soporte predeterminado de respaldo para otros navegadores. Incluso si el navegador no admite la API de View Transitions, Astro seguirá proporcionando navegación en el navegador utilizando una de las opciones de respaldo para obtener una experiencia comparable.
Dependiendo del soporte del navegador, es posible que necesites establecer explícitamente en las directivas de transición name
o animate
en los elementos que deseas animar para obtener una experiencia comparable en todos los navegadores:
---import Layout from "../layouts/LayoutUsingClientRouter.astro";---<title transition:animate="fade">About my site</title>
Puedes sobreescribir el soporte de respaldo predeterminado de Astro agregando una propiedad fallback
en el componente <ViewTransitions />
y estableciéndolo en swap
o none
:
animate
(predeterminado, recomendado) - Astro simulará view transitions utilizando atributos personalizados antes de actualizar el contenido de la página.swap
- Astro no intentará animar la página. En su lugar, la página antigua será reemplazada inmediatamente por la nueva.none
- Astro no realizará ninguna transición animada de página. En su lugar, obtendrás navegación de página completa en navegadores que no admitan esta función.
---import { ClientRouter } from "astro:transitions";---<title>Mi sitio</title>
<ClientRouter fallback="swap" />
La animación del navegador initial
no es simulada por Astro. Por lo tanto, cualquier elemento que utilice esta animación no será animado.
Proceso de navegación del lado del cliente
Sección titulada «Proceso de navegación del lado del cliente»Cuando se utiliza el enrutador <ClientRouter />
, se siguen los siguientes pasos para llevar a cabo la navegación del lado del cliente en Astro:
-
Un visitante de tu sitio desencadena la navegación mediante cualquiera de las siguientes acciones:
- Haciendo clic en una etiqueta
<a>
que enlaza internamente a otra página de tu sitio. - Haciendo clic en el botón de retroceso.
- Haciendo clic en el botón de avance.
- Haciendo clic en una etiqueta
-
El enrutador comienza a buscar la siguiente página.
-
El enrutador agrega el atributo
data-astro-transition
al elemento HTML con un valor de'forward'
o'back'
según corresponda. -
El enrutador llama a
document.startViewTransition
. Esto desencadena el propio proceso de transición de vista del navegador. Es importante destacar que el navegador captura una captura de pantalla del estado actual de la página. -
Dentro del callback de
startViewTransition
, el enrutador realiza un intercambio, que consta de la siguiente secuencia de eventos:-
El contenido de
<head>
se intercambia, manteniendo algunos elementos:- Los nodos DOM de las hojas de estilo se mantienen si existen en la nueva página, para evitar el parpadeo de contenido no estilizado (FOUC).
- Los scripts se mantienen si existen en la nueva página.
- Cualquier otro elemento de
<head>
contransition:persist
se mantiene si hay un elemento correspondiente en la nueva página.
-
<body>
se reemplaza completamente con el cuerpo de la nueva página. -
Los elementos marcados con
transition:persist
se trasladan al nuevo DOM si existen en la nueva página. -
La posición de desplazamiento se restaura si es necesario.
-
Se desencadena el evento
astro:after-swap
en eldocument
. Esto marca el final del proceso de intercambio.
-
-
El enrutador espera a que se carguen las nuevas hojas de estilo antes de resolver la transición.
-
El enrutador ejecuta cualquier nuevo script agregado a la página.
-
Se dispara el evento
astro:page-load
. Esto marca el final del proceso de navegación.
Comportamiento del script con view transitions
Sección titulada «Comportamiento del script con view transitions»Al añadir view transitions a un proyecto de Astro existente, es posible que algunos de tus scripts ya no se vuelvan a ejecutar tras la navegación por la página, como ocurría con las actualizaciones de página completa del navegador. Utiliza la siguiente información para asegurarte de que tus scripts se ejecutan como se espera.
Orden del Script
Sección titulada «Orden del Script»Al navegar entre páginas con el componente <ClientRouter />
, los scripts se ejecutan en orden secuencial para ajustarse al comportamiento del navegador.
Reejecución del script
Sección titulada «Reejecución del script»Los Bundled module scripts, que son los scripts por defecto en Astro, sólo se ejecutan una vez. Después de la ejecución inicial serán ignorados, incluso si el script existe en la nueva página después de una transición.
A diferencia de los scripts de módulos empaquetados, los scripts inline pueden volver a ejecutarse durante la visita de un usuario a un sitio si existen en una página que se visita varias veces. Los scripts inline también pueden volver a ejecutarse cuando un visitante navega a una página sin el script y luego vuelve a una con el script.
Con las view transitions, algunos scripts pueden dejar de ejecutarse después de la navegación entre páginas, a diferencia de lo que ocurre con una recarga completa del navegador. Existen varios eventos durante el enrutamiento del lado del cliente a los que puedes escuchar, y puedes disparar acciones cuando ocurren. Puedes envolver un script existente dentro de un listener de eventos para asegurarte de que se ejecute en el momento adecuado del ciclo de navegación.
El siguiente ejemplo envuelve un script para un menú móvil tipo “hamburguesa” dentro de un listener del evento astro:page-load
, el cual se ejecuta al final de la navegación entre páginas, haciendo que el menú responda correctamente al hacer clic después de navegar a una nueva página:
document.addEventListener("astro:page-load", () => { document.querySelector(".hamburger").addEventListener("click", () => { document.querySelector(".nav-links").classList.toggle("expanded"); });});
El siguiente ejemplo muestra una función que se ejecuta en respuesta al evento astro:after-swap
, el cual ocurre inmediatamente después de que la nueva página ha reemplazado a la anterior y antes de que los elementos del DOM se pinten en la pantalla. Esto evita un destello del tema en modo claro después de la navegación, verificando y, si es necesario, estableciendo el tema en modo oscuro antes de que se renderice la nueva página:
<script is:inline> function applyTheme() { localStorage.theme === "dark" ? document.documentElement.classList.add("dark") : document.documentElement.classList.remove("dark"); }
document.addEventListener("astro:after-swap", applyTheme); applyTheme();</script>
data-astro-rerun
Sección titulada «data-astro-rerun»
Agregado en:
astro@4.5.0
Para forzar a los scripts inline a reejecutarse después de cada transición, añade la propiedad data-astro-rerun
. Al añadir cualquier atributo a un script también se añade implícitamente is:inline
, por lo que esto sólo está disponible para scripts que no están empaquetados y procesados por Astro.
<script is:inline data-astro-rerun>...</script>
Para garantizar que un script se ejecuta cada vez que se carga una página durante la navegación del lado del cliente, debe ser ejecutado por un evento del ciclo de vida. Por ejemplo, los escuchadores de eventos para DOMContentLoaded
pueden sustituirse por el evento de ciclo de vida astro:page-load
.
Si tienes código que establece un estado global en un script inline, este estado necesitará tener en cuenta que el script podría ejecutarse más de una vez. Comprueba el estado global en tu etiqueta <script>
, y ejecuta condicionalmente tu código cuando sea posible. Esto funciona porque window
se mantiene.
<script is:inline> if (!window.SomeGlobal) { window.SomeGlobal = {}; }</script>
Eventos del ciclo de vida
Sección titulada «Eventos del ciclo de vida»El enrutador <ClientRouter />
proporciona varios eventos en el document
durante la navegación. Estos eventos proporcionan hooks en el ciclo de vida de la navegación, permitiéndote realizar acciones como mostrar indicadores de que la nueva página está cargado, sobrescribe el comportamiento predeterminado y restablece el estado mientras se completa la navegación.
El proceso de navegación implica una fase de preparación, cuando el nuevo contenido es cargado; una fase de intercambio de DOM, donde el contenido de la página antigua se sustituye por el de la nueva; y una fase de finalización donde los scripts son ejecutados, la carga se informa como completada y se realiza un trabajo de limpieza.
Los eventos del ciclo de vida de la API de View Transitions de Astro, en orden, son:
El evento before-
te permite influir y modificar acciones que están a punto de producirse y los after-
son notificaciones de que se ha completado una fase.
Mientras algunas acciones pueden ser disparadas durante cualquier evento, algunas tareas solo pueden realizarse durante un evento especifico para mejores resultados, como mostrar un spinner de carga antes de la preparación o sobrescribir pares de animaciones antes de intercambiar el contenido.
astro:before-preparation
Sección titulada «astro:before-preparation»
Agregado en:
astro@3.6.0
Un evento que es disparado al inicio de la fase de preparación, después de que la navegación ha comenzado (p. ej. después de que el usuario haya clicado un enlace), pero antes de que el contenido es cargado.
Este evento es usado:
- Para hacer algo antes de que la carga haya comenzado, como mostrar un spinner de carga.
- Para modificar la carga, como cargar el contenido que has definido en una plantilla en lugar de una URL externa.
- Para cambiar la
dirección
de la navegación (que suele seradelante
oatrás
) para realizar una animación personalizada.
Aquí hay un ejemplo usando el evento astro:before-preparation
para cargar un spinner antes de que se cargue el contenido y pararlo inmediatamente depués la carga.
Ten en cuenta que el uso del callback del loader de esta manera permite la ejecución asíncrona del código.
<script is:inline> document.addEventListener("astro:before-preparation", (event) => { const originalLoader = event.loader; event.loader = async function () { const { startSpinner } = await import("./spinner.js"); const stop = startSpinner(); await originalLoader(); stop(); }; });</script>
astro:after-preparation
Sección titulada «astro:after-preparation»
Agregado en:
astro@3.6.0
Un evento que es diparado al final de la fase de preparación, después de que el contenido de la nueva página haya sido cargado y analizado en un documento. Este evento ocurre antes de la fase de view transitions.
Este ejemplo usa el evento astro:before-preparation
para comenzar un indicador de carga y el evento astro:after-preparation
para pararlo:
<script is:inline> document.addEventListener("astro:before-preparation", () => { document.querySelector("#loading").classList.add("show"); }); document.addEventListener("astro:after-preparation", () => { document.querySelector("#loading").classList.remove("show"); });</script>
Esta es una versión más sencilla de un spinner de carga que el ejemplo mostrado anteriormente: si todo el código de los listener’s puede ejecutarse de forma síncrona, no es necesario conectarse al callback del loader.
astro:before-swap
Sección titulada «astro:before-swap»
Agregado en:
astro@3.6.0
Un evento que es disparado antes de que el nuevo documento (que se completa durante la fase de preparación) reemplace el documento actual. Este evento ocurre dentro de una view transition, donde el usuario sigue viendo una instantánea de la página anterior.
Este evento puede ser usado para realizar cambios antes de que el intercambio ocurra. La propiedad newDocument
en el evento representa el documento entrante. Aquí hay un ejempl para asegurar que la preferencia del modo claro u oscuro del navegador en localStorage
se traslada a la nueva página:
<script is:inline> function setDarkMode(document) { let theme = localStorage.darkMode ? "dark" : "light"; document.documentElement.dataset.theme = theme; }
setDarkMode(document);
document.addEventListener("astro:before-swap", (event) => { // Pass the incoming document to set the theme on it setDarkMode(event.newDocument); });</script>
El evento astro:before-swap
también puede ser usado para cambiar la implementación del intercambio. La implementación del intercambio por defecto compara el contenido principal, mueve elementos persistentes del antiguo documento al newDocument
, y luego reemplaza todo el body
con el body del nuevo documento.
En este punto del ciclo de vida, podrías optar por definir tu propia implementación de intercambio, por ejemplo, para comparar todo el contenido del documento existente (como hacen algunos otros enrutadores):
<script is:inline> document.addEventListener("astro:before-swap", (event) => { event.swap = () => { diff(document, event.newDocument); }; });</script>
Crear una función de intercambio personalizada
Sección titulada «Crear una función de intercambio personalizada»El objeto swapFunctions
del módulo astro:transitions/client
proporciona cinco funciones utilitarias que manejan tareas específicas relacionadas con el intercambio, incluyendo el manejo de atributos del documento, elementos de la página y ejecución de scripts. Estas funciones se pueden usar directamente para definir una implementación personalizada del intercambio.
El siguiente ejemplo demuestra cómo usar estas funciones para recrear la implementación de intercambio incorporada de Astro:
<script> import { swapFunctions } from "astro:transitions/client";
// substitutes `window.document` with `doc` function mySwap(doc: Document) { swapFunctions.deselectScripts(doc); swapFunctions.swapRootAttributes(doc); swapFunctions.swapHeadElements(doc); const restoreFocusFunction = swapFunctions.saveFocus(); swapFunctions.swapBodyElement(doc.body, document.body); restoreFocusFunction(); }
document.addEventListener("astro:before-swap", (event) => { event.swap = () => mySwap(event.newDocument); });<script>
Las implementaciones personalizadas de intercambio pueden comenzar con esta plantilla y agregar o reemplazar pasos individuales con lógica personalizada según sea necesario.
astro:after-swap
Sección titulada «astro:after-swap»Un evento que se dispara inmediatamente después de que la nueva página reemplace la página antigua. Puedes escuchar este evento en el document
y desencadenar acciones que ocurrirán antes de que se rendericen los elementos DOM de la nueva página y se ejecuten los scripts.
Este evento, cuando se escucha en la página saliente, es útil para pasar y restaurar cualquier estado en el DOM que necesite transferirse a la nueva página.
Este es el último punto en el ciclo de vida donde sigue siendo seguro para, por ejemplo, añadir un nombre de clase para el modo oscuro (<html class="dark-mode">
), aunque podrías hacerlo en un evento anterior.
El evento astro:after-swap
ocurre inmediatamente después de que el historial del navegador haya sido actualizado y la posición del scroll haya sido establecida. Por lo tanto, un uso de este evento es sobreescribir la restauración predeterminada para la navegación en el historial. El siguiente ejemplo restablece la posición del scroll horizontal y vertical en la esquina superior izquierda de la página para cada navegación.
document.addEventListener("astro:after-swap", () => window.scrollTo({ left: 0, top: 0, behavior: "instant" }),);
astro:page-load
Sección titulada «astro:page-load»Un evento que se dispara al final de la navegación de la página, después de que la nueva página es visible para el usuario y se han cargado los estilos y scripts bloqueantes. Puedes escuchar este evento en el document
.
El componente <ClientRouter />
dispara este evento se dispara tanto en la navegación inicial de la página para una página pre-renderizada como en cualquier navegación posterior, ya sea hacia delante o hacia atrás.
Puedes usar este evento para ejecutar código en cada navegación de página, o sólo una vez:
<script> document.addEventListener("astro:page-load", () => { // Esto se ejecuta en la primera carga de la página y después de cada navegación setupStuff(); // por ejemplo, agregar escuchadores de eventos });</script>
Accesibilidad
Sección titulada «Accesibilidad»Habilitar la navegación del lado del cliente y animar las view transitions presentan desafíos de accesibilidad, y Astro tiene como objetivo hacer que los sitios que optan por las View Transitions sean accesibles por defecto en la medida de lo posible.
Anuncio de ruta
Sección titulada «Anuncio de ruta»
Agregado en:
astro@3.2.0
El componente <ClientRouter />
incluye un anunciador de ruta para la navegación de páginas durante la navegación del lado del cliente. No se necesita configuración ni acción para habilitar esto.
Las tecnologías de asistencia permiten que los visitantes sepan que la página ha cambiado anunciando el nuevo título de la página después de la navegación. Cuando se utiliza la navegación del lado del servidor con recargas tradicionales de la página completa en el navegador, esto ocurre automáticamente después de que la nueva página se carga. En la navegación del lado del cliente, el componente <ClientRouter />
realiza esta acción.
Para agregar un anuncio de ruta a la navegación del lado del cliente, el componente agrega un elemento a la nueva página con el atributo aria-live
configurado en assertive
. Esto indica a las AT (tecnologías de asistencia) que deben anunciar inmediatamente. El componente también verifica lo siguiente, en orden de prioridad, para determinar el texto del anuncio:
- El
<title>
, si existe. - El primer
<h1>
que encuentre. - La
pathname
de la página.
Recomendamos encarecidamente que siempre incluyas un elemento <title>
en cada página por razones de accesibilidad.
prefers-reduced-motion
Sección titulada «prefers-reduced-motion»El componente <ViewTransitions />
de Astro incluye una media query de CSS que deshabilita todas las animaciones de transición de vista, incluida la animación de respaldo, siempre que se detecte la configuración prefer-reduced-motion
. En su lugar, el navegador simplemente intercambiará los elementos DOM sin una animación.