Анимации переходов
Astro поддерживает переходы между представлениями всего несколькими строками кода. Такие переходы обновляют содержимое страницы без стандартной полной перезагрузки навигации в браузере и обеспечивают плавную анимацию между страницами. В тех случаях, когда браузер не поддерживает View Transition API, Astro позволяет управлять стратегиями запасных вариантов, обеспечивая наилучший опыт для всех пользователей.
Astro предоставляет компонент маршрутизации <ClientRouter />
, который можно добавить в <head>
отдельной страницы, чтобы управлять переходами между страницами. Он предоставляет лёгкий маршрутизатор на стороне клиента, который перехватывает навигацию и позволяет настраивать переход между страницами.
Добавьте этот компонент к многократно используемому компоненту .astro
, например, к общему элементу <head>
или макету, для анимированных переходов страниц на всем сайте (режим SPA).
Поддержка анимации переходов в Astro осуществляется с помощью нового API браузера View Transitions и также включает в себя:
- Несколько встроенных директив анимации, таких как
fade
,lide
иnone
. - Поддержку анимации навигации вперёд и назад.
- Возможность полностью настраивать все аспекты анимации переходов и создавать собственные анимации.
- Опцию предотвращения навигации на стороне клиента для нестраничных ссылок.
- Контроль над поведением по умолчанию для браузеров, которые ещё не поддерживают API View Transitions.
- Автоматическую поддержку
prefers-reduced-motion
.
По умолчанию на каждой странице будет использоваться обычная, полностраничная навигация браузера. Для просмотра переходов необходимо зарегистрироваться, а использовать их можно как для каждой страницы, так и для всего сайта.
Добавление анимации переходов на страницу
Заголовок раздела Добавление анимации переходов на страницуПерейдите к использованию переходов между представлениями на отдельных страницах, импортировав и добавив компонент маршрутизации <ClientRouter />
в <head>
на каждой нужной странице.
---import { ClientRouter } from 'astro:transitions';---<html lang="ru"> <head> <title>Моя домашняя страница</title> <ClientRouter /> </head> <body> <h1>Добро пожаловать на мой сайт!</h1> </body></html>
Полноценные переходы между страницами сайта (режим SPA)
Заголовок раздела Полноценные переходы между страницами сайта (режим SPA)Импортируйте и добавьте компонент <ClientRouter />
в общий компонент <head>
или общий компонент макета. Astro создаст анимацию страницы по умолчанию, основываясь на сходстве между старой и новой страницами, а также обеспечит обратное поведение для неподдерживаемых браузеров.
В приведённом ниже примере показано добавление анимации навигации по страницам, используемой Astro по умолчанию для всего сайта, включая вариант управления по умолчанию для неподдерживающих браузеров, путём импорта и добавления этого компонента в компонент <CommonHead />
Astro:
---import { ClientRouter } from 'astro:transitions';---<link rel="icon" type="image/svg+xml" href="/favicon.svg" /><meta name="generator" content={Astro.generator} />
<!-- Основные метатеги --><title>{title}</title><meta name="title" content={title} /><meta name="description" content={description} />
<ClientRouter />
Для включения стандартной навигации Astro на стороне клиента не требуется никаких других настроек!
Для более тонкого контроля используйте директивы переходов или переопределите навигацию по умолчанию на стороне клиента для отдельных элементов.
Директивы переходов
Заголовок раздела Директивы переходовAstro автоматически присвоит соответствующим элементам, находящимся как на старой, так и на новой странице, общее уникальное имя view-transition-name
. Эта пара совпадающих элементов определяется как по типу элемента, так и по его расположению в DOM.
Используйте необязательные директивы transition:*
для элементов страницы в компонентах .astro
для более тонкого контроля над поведением перехода страницы во время навигации.
transition:name
: Позволяет переопределить стандартное сопоставление элементов в Astro для анимации старого/нового контента и указать имя перехода, чтобы связать пару элементов DOM.transition:animate
: Позволяет отменить анимацию по умолчанию в Astro, заменив старый элемент на новый, указав тип анимации. Используйте встроенные директивы анимации или создайте собственные анимации переходов в Astro.transition:persist
: Позволяет отменить стандартную замену Astro старых элементов на новые и вместо этого сохранять компоненты и HTML-элементы при переходе на другую страницу.
Именование перехода
Заголовок раздела Именование переходаВ некоторых случаях вам может понадобиться самостоятельно определить соответствующие элементы анимации перехода. Вы можете задать имя для пары элементов с помощью директивы transition:name
.
<aside transition:name="hero">
<aside transition:name="hero">
Обратите внимание, что предоставленное значение transition:name
может быть использовано только один раз на каждой странице. Установите этот параметр вручную, если Astro не может самостоятельно определить правильное имя, или для более тонкого контроля над сопоставлением элементов.
Поддержание состояния
Заголовок раздела Поддержание состояния
Добавлено в:
astro@2.10.0
Можно сохранять компоненты и HTML-элементы (вместо того, чтобы заменять их) при переходе по странице с помощью директивы transition:persist
.
Например, следующее <video>
будет продолжать воспроизводиться при переходе на другую страницу, содержащую тот же видеоэлемент. Это работает как при навигации вперёд, так и назад.
<video controls muted autoplay transition:persist> <source src="https://ia804502.us.archive.org/33/items/GoldenGa1939_3/GoldenGa1939_3_512kb.mp4" type="video/mp4" /></video>
Вы также можете поместить директиву на островок Astro (компонент UI-фреймворка с директивой client:
(EN)). Если этот компонент существует на следующей странице, островок со старой страницы с его текущим состоянием будет продолжать отображаться, а не заменяться островком с новой страницы.
В приведённом ниже примере внутреннее состояние счётчика компонента не будет сбрасываться при переходе туда и обратно по страницам, содержащим компонент <Counter />
с атрибутом transition:persist
.
<Counter client:load transition:persist initialCount={5} />
Не все состояния можно сохранить таким образом. Перезапуск CSS-анимации и перезагрузка фреймов не могут быть предотвращены при переходе между представлениями даже при использовании transition:persist
.
Вы также можете вручную идентифицировать соответствующие элементы, если островок/элемент находится в другом компоненте между двумя страницами.
<video controls muted autoplay transition:name="media-player" transition:persist/>
<MyVideo controls muted autoplay transition:name="media-player" transition:persist/>
В качестве удобного сокращения transition:persist
также может принимать в качестве значения имя перехода.
<video controls muted autoplay transition:persist="media-player">
transition:persist-props
Заголовок раздела transition:persist-props
Добавлено в:
astro@4.5.0
Это позволяет вам контролировать, должны ли входные данные (пропсы) островка сохраняться при навигации.
По умолчанию, когда вы добавляете transition:persist
к островку, состояние сохраняется при навигации, но ваш компонент будет повторно отображаться с новыми входными данными. Это полезно, например, когда компонент получает свойства, специфичные для страницы, такие как заголовок текущей страницы.
Вы можете переопределить это поведение с помощью transition:persist-props
. Добавление этой директивы сохранит существующие пропсы островка (без повторной визуализации с новыми значениями) в дополнение к сохранению существующего состояния.
Встроенные директивы анимации
Заголовок раздела Встроенные директивы анимацииAstro поставляется с несколькими встроенными анимациями, позволяющими переопределить переход fade
по умолчанию. Добавьте директиву transition:animate
к отдельным элементам, чтобы настроить поведение определённых переходов.
fade
(по умолчанию): Предустановленная анимация перекрёстного затухания. Старое содержимое исчезает, новое появляется с эффектом плавного появления.initial
: Отключает предустановленную анимацию Astro, используется стандартное оформление браузера.slide
: Анимация, при которой старое содержимое уходит влево, а новое появляется справа. При обратной навигации анимация воспроизводится в обратном направлении.none
: Отключает анимации браузера по умолчанию. Применяйте к элементу<html>
страницы, чтобы отключить анимацию затухания для всех элементов на странице.
Комбинируйте директивы для полного контроля над анимацией вашей страницы. Установите значение страницы по умолчанию для элемента <html>
и переопределите его для любых отдельных элементов, если требуется.
В приведённом ниже примере создается слайд-анимация для основного содержимого при отключении анимации затухания браузера по умолчанию для остальной части страницы:
---import CommonHead from '../components/CommonHead.astro';---
<html transition:name="root" transition:animate="none"> <head> <CommonHead /> </head> <body> <header> ... </header> <!-- Переопределяем страницу по умолчанию для одного элемента --> <main transition:animate="slide"> ... </main> </body></html>
Настройка анимации
Заголовок раздела Настройка анимацииМожно настроить все аспекты перехода с помощью любых свойств анимации CSS.
Чтобы настроить встроенную анимацию, сначала импортируйте её из astro:transitions
, а затем передайте параметры настройки.
В приведённом ниже примере настраивается длительность встроенной анимации fade
:
---import { fade } from 'astro:transitions';---<header transition:animate={fade({ duration: '0.4s' })}>
Вы также можете определить собственные анимации для использования с transition:animate
, задекларировав поведение как для перехода вперёд, так и назад, а также для новых и старых страниц, в соответствии со следующими типами:
export interface TransitionAnimation { name: string; // Имя ключевого кадра 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;}
Следующий пример демонстрирует все необходимые свойства для определения пользовательской анимации bump
внутри тега <style is:global>
в вашем корневом файле макета:
---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>
Поведение анимации должно быть определено в метаданных каждого компонента, использующего эту анимацию:
---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>
У вас есть большая гибкость при определении пользовательских анимаций. Для достижения желаемого результата вы можете рассмотреть необычные комбинации, например, использовать разные объекты для перехода вперёд и назад, или предоставить отдельные анимации ключевых кадров для старых и новых элементов.
Управление маршрутизатором
Заголовок раздела Управление маршрутизаторомМаршрутизатор <ClientRouter />
обрабатывает навигацию, прослушивая:
- Клики по элементам
<a>
. - События навигации назад и вперёд.
Следующие опции позволяют дополнительно контролировать процесс навигации в маршрутизаторе:
data-astro-reload
: Атрибут тега<a>
для принудительной полностраничной навигацииdata-astro-history="auto | push | replace"
: атрибут тега<a>
для управления историей браузераnavigate(href, options)
: метод, доступный любому клиентскому скрипту или клиентскому компоненту для запуска навигации
Предотвращение навигации на стороне клиента
Заголовок раздела Предотвращение навигации на стороне клиентаВ некоторых случаях навигация с помощью маршрутизации на стороне клиента невозможна, поскольку обе страницы должны использовать маршрутизатор <ClientRouter />
, чтобы предотвратить перезагрузку всей страницы. Возможно, вам также не нужна маршрутизация на стороне клиента при каждом изменении навигации, и вы предпочтёте традиционную постраничную навигацию по выбранным маршрутам.
Вы можете отказаться от маршрутизации на стороне клиента для каждой ссылки, добавив атрибут data-astro-reload
к любому тегу <a>
или <form>
. Этот атрибут отменяет все существующие компоненты <ClientRouter />
и вместо этого запускает обновление браузера во время навигации.
Следующий пример показывает, как предотвратить клиентскую маршрутизацию при переходе к статье только с главной страницы. Это всё ещё позволяет использовать анимацию на общих элементах, таких как главное изображение, при переходе на ту же страницу со страницы списка статей:
<a href="/articles/emperor-penguins" data-astro-reload>
<a href="/articles/emperor-penguins">
Ссылки с атрибутом data-astro-reload
будут проигнорированы маршрутизатором, и произойдёт полностраничная навигация.
Навигация по триггерам
Заголовок раздела Навигация по триггерамВы также можете запускать навигацию на стороне клиента по событиям, которые обычно не прослушиваются маршрутизатором <ClientRouter />
, используя navigate
. Эта функция из модуля astro:transitions/client
может использоваться в скриптах, а также в компонентах фреймворка, которые гидратированы с помощью директивы client (EN).
В следующем примере показан компонент Astro, который переводит посетителя на другую страницу, выбранную им из меню:
<script> import { navigate } from 'astro:transitions/client';
// Navigate to the selected option automatically. document.querySelector('select').onchange = (ev) => { let href = ev.target.value; navigate(href); };</script><select> <option value="/play">Игра</option> <option value="/blog">Блог</option> <option value="/about">О сайте</option> <option value="/contact">Контакты</option></select>
---import Form from "../components/Form.astro";import { ClientRouter } from "astro:transitions";---<html> <head> <ClientRouter /> </head> <body> <Form /> </body></html>
Следующий пример реализует то же самое с помощью navigate()
в компоненте React <Form />
:
import { navigate } from "astro:transitions/client";
export default function Form() { return ( <select onChange={(e) => navigate(e.target.value)}> <option value="/play">Игра</option> <option value="/blog">Блог</option> <option value="/about">О сайте</option> <option value="/contact">Контакты</option> </select> );}
Компонент <Form />
может быть отображен на странице Astro, использующей маршрутизатор <ClientRouter />
, с помощью директивы client
:
---import Form from "../components/Form.jsx";import { ClientRouter } from "astro:transitions";---<html> <head> <ClientRouter /> </head> <body> <Form client:load /> </body></html>
Метод navigate
принимает эти аргументы:
href
(обязательно) - Новая страница, на которую нужно перейти.options
- Необязательный объект со следующими свойствами:history
:'push'
|'replace'
|'auto'
'push'
: маршрутизатор будет использоватьhistory.pushState
для создания новой записи в истории браузера.'replace'
: маршрутизатор будет использоватьhistory.replaceState
для обновления URL без добавления новой записи в навигацию.'auto'
(по умолчанию): маршрутизатор попытается использоватьhistory.pushState
, но если URL не является тем, на который можно перейти, текущий URL останется без изменений в истории браузера.
formData
: ОбъектFormData
дляPOST
запросов.
Для навигации по истории браузера назад и вперёд можно комбинировать navigate()
со встроенными функциями браузера history.back()
, history.forward()
и history.go()
. Если navigate()
вызывается во время отрисовки компонента на стороне сервера, это не имеет никакого эффекта.
Замена записей в истории браузера
Заголовок раздела Замена записей в истории браузераОбычно при каждом переходе новая запись записывается в историю браузера. Это позволяет перемещаться между страницами с помощью кнопок браузера назад
и вперёд
.
Маршрутизатор <ClientRouter />
позволяет перезаписывать записи истории, добавляя атрибут data-astro-history
к любому отдельному тегу <a>
.
Атрибут data-astro-history
может иметь те же три значения, что и опция history
функции navigate()
:
data-astro-history
: 'push'
| 'replace'
| 'auto'
'push'
: маршрутизатор будет использоватьhistory.pushState
для создания новой записи в истории браузера.'replace'
: маршрутизатор будет использоватьhistory.replaceState
для обновления URL без добавления новой записи в навигацию.'auto'
(по умолчанию): маршрутизатор попытается использоватьhistory.pushState
, но если URL не является тем, на который можно перейти, текущий URL останется без изменений в истории браузера.
Следующий пример переходит на страницу /main
, но не добавляет новую запись в историю просмотров. Вместо этого он использует текущую запись в истории (/confirmation
) и перезаписывает её.
<a href="/main" data-astro-history="replace">
В результате, если вы вернетесь со страницы /main
, браузер отобразит не страницу /confirmation
, а страницу перед ней.
Переходы с формами
Заголовок раздела Переходы с формами
Добавлено в:
astro@4.0.0
Маршрутизатор <ClientRouter />
запускает внутристраничные переходы из элементов <form>
, поддерживая как GET
, так и POST
запросы.
По умолчанию Astro отправляет данные формы в формате multipart/form-data
, когда атрибут method
имеет значение POST
. Если вы хотите соответствовать стандартному поведению веб-браузеров, используйте атрибут enctype
для отправки данных в кодировке application/x-www-form-urlencoded
:
<form action="/contact" method="POST" enctype="application/x-www-form-urlencoded">
Можно отказаться от переходов маршрутизатора на любой отдельной форме с помощью атрибута data-astro-reload
:
<form action="/contact" data-astro-reload>
Запасные варианты
Заголовок раздела Запасные вариантыМаршрутизатор <ClientRouter />
лучше всего работает в браузерах с поддержкой View Transitions (например, в браузерах на движке Chromium), но также включает поддержку запасных вариантов для других браузеров. Даже если браузер не поддерживает View Transitions API, клиентский маршрутизатор Astro всё равно может обеспечивать навигацию внутри браузера с использованием одного из запасных решений.
В зависимости от поддержки браузером, вам может потребоваться явно указать директивы перехода name
или animate
(директивы переходов) для элементов, которые вы хотите анимировать, чтобы обеспечить сопоставимый пользовательский опыт во всех браузерах:
---import Layout from "../layouts/LayoutUsingClientRouter.astro";---<title transition:animate="fade">О моём сайте</title>
Можно переопределить поддержку поведения по умолчанию в Astro, добавив свойство fallback
для компонента <ClientRouter />
и установив для него значение swap
или none
:
animate
(по умолчанию, рекомендуется) - перед обновлением содержимого страницы Astro будет имитировать анимацию переходов с помощью пользовательских атрибутов.swap
- Astro не будет пытаться анимировать страницу. Вместо этого старая страница будет немедленно заменена новой.none
- Astro не будет делать никаких анимированных переходов между страницами. Вместо этого вы получите полностраничную навигацию в неподдерживающих браузерах.
---import { ClientRouter } from 'astro:transitions';---<title>Мой сайт</title>
<ClientRouter fallback="swap" />
Браузерная анимация initial
не имитируется Astro. Таким образом, любой элемент, использующий эту анимацию, в данный момент не будет анимирован.
Процесс навигации на стороне клиента
Заголовок раздела Процесс навигации на стороне клиентаПри использовании маршрутизатора <ClientRouter />
для создания навигации Astro на стороне клиента выполняются следующие действия:
-
Посетитель вашего сайта запускает навигацию любым из следующих действий:
- Щелчок по тегу
<a>
, содержащему внутреннюю ссылку на другую страницу вашего сайта. - Нажатие кнопки «Назад».
- Нажатие кнопки «Вперёд».
- Щелчок по тегу
-
Маршрутизатор начинает поиск следующей страницы.
-
Маршрутизатор добавляет атрибут
data-astro-transition
к элементу HTML со значением'forward'
или'back'
в зависимости от ситуации. -
Маршрутизатор вызывает
document.startViewTransition
. Это запускает собственный процесс анимации переходов браузера. Важно, что браузер делает скриншот текущего состояния страницы. -
Внутри обратного вызова
startViewTransition
маршрутизатор выполняет процесс swap, который состоит из следующей последовательности событий:-
Содержимое
<head>
меняется местами, а некоторые элементы сохраняются:- Узлы DOM таблицы стилей оставляются, если они существуют на новой странице, чтобы предотвратить появление неоформленного контента при загрузке.
- Скрипты оставляются, если они существуют на новой странице.
- Любые другие элементы заголовка с
transition:persist
остаются, если на новой странице есть соответствующий элемент.
-
<body>
полностью заменяется телом новой страницы. -
Элементы с пометкой
transition:persist
переносятся в новый DOM, если они существуют на новой странице. -
При необходимости положение прокрутки восстанавливается.
-
Событие
astro:after-swap
срабатывает надокументе
. На этом процесс swap заканчивается.
-
-
Маршрутизатор ожидает загрузки новых таблиц стилей, прежде чем разрешить переход.
-
Маршрутизатор выполняет все новые скрипты, добавленные на страницу.
-
Срабатывает событие
astro:page-load
. На этом процесс навигации заканчивается.
Поведение скриптов при анимации переходов
Заголовок раздела Поведение скриптов при анимации переходовКогда вы добавляете анимацию переходов в существующий проект Astro, некоторые из ваших скриптов больше не могут повторно запускаться после перехода по странице, как это происходило при обновлении браузера на всю страницу. Используйте следующую информацию, чтобы убедиться, что ваши сценарии выполняются так, как ожидается.
Порядок выполнения скриптов
Заголовок раздела Порядок выполнения скриптовПри переходе между страницами с помощью компонента <ClientRouter/>
скрипты запускаются в последовательном порядке, чтобы соответствовать поведению браузера.
Повторное выполнение скриптов
Заголовок раздела Повторное выполнение скриптовСкрипты встроенных модулей, которые являются скриптами по умолчанию в Astro, выполняются только один раз. После первоначального выполнения они будут игнорироваться, даже если скрипт будет существовать на новой странице после перехода.
В отличие от скриптов встроенных модулей, встроенные скрипты могут быть повторно выполнены во время посещения сайта пользователем, если они находятся на странице, которая посещается несколько раз. Встроенные скрипты могут также повторно выполняться, когда посетитель переходит на страницу без скрипта, а затем обратно на страницу со скриптом.
С переходами представлений некоторые скрипты могут перестать повторно выполняться после навигации по странице, как это происходит при полной перезагрузке страницы в браузере. Существует несколько событий во время клиентской маршрутизации, которые вы можете отслеживать, и запускать события, когда они происходят. Вы можете обернуть существующий скрипт в слушатель событий, чтобы гарантировать его выполнение в нужный момент цикла навигации.
Следующий пример оборачивает скрипт для мобильного меню в стиле «гамбургер» в слушатель событий для astro:page-load
, который срабатывает в конце навигации по странице, чтобы сделать меню реагирующим на клики после перехода на новую страницу:
document.addEventListener("astro:page-load", () => { document.querySelector(".hamburger").addEventListener("click", () => { document.querySelector(".nav-links").classList.toggle("expanded"); });});
Следующий пример показывает функцию, которая выполняется в ответ на событие astro:after-swap
, происходящее сразу после того, как новая страница заменила старую, но до того, как элементы DOM будут отрисованы на экране. Это позволяет избежать вспышки светлой темы после навигации по странице, проверяя и, при необходимости, устанавливая тёмную тему до того, как новая страница будет отображена:
<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
Заголовок раздела data-astro-rerun
Добавлено в:
astro@4.5.0
Чтобы заставить встроенные скрипты повторно выполняться после каждого перехода, добавьте свойство data-astro-rerun
. Добавление любого атрибута к скрипту также неявно добавляет is:inline
, поэтому это доступно только для скриптов, которые не собираются и не обрабатываются Astro.
<script is:inline data-astro-rerun>...</script>
Чтобы скрипт запускался каждый раз при загрузке страницы во время навигации на стороне клиента, он должен выполняться по событию жизненного цикла. Например, слушатели событий для DOMContentLoaded
могут быть заменены событием жизненного цикла astro:page-load
.
Если у вас есть код, который устанавливает глобальное состояние во встроенном скрипте, это состояние должно учитывать, что скрипт может выполняться более одного раза. Проверьте глобальное состояние в теге <script>
и по возможности выполняйте код условно. Это работает, потому что window
сохраняется.
<script is:inline> if (!window.SomeGlobal) { window.SomeGlobal = {} // .... }</script>
События жизненного цикла
Заголовок раздела События жизненного циклаМаршрутизатор <ViewTransition />
вызывает ряд событий на документе
во время навигации. Эти события позволяют подключаться к жизненному циклу навигации, чтобы показывать индикаторы загрузки новой страницы, переопределять поведение по умолчанию и восстанавливать состояние по завершении навигации.
Процесс навигации включает в себя фазу подготовки, когда загружается новый контент; этап DOM swap, на котором содержимое старой страницы заменяется содержимым новой; и фаза завершения, на которой выполняются скрипты, сообщается о завершении загрузки и выполняется очистка.
События жизненного цикла API View Transition от Astro расположены в следующем порядке:
События before-
позволяют вам влиять на действия, которые должны произойти, и изменять их, а события after-
— это уведомления о завершении этапа.
Хотя некоторые действия могут быть вызваны во время любого события, некоторые задачи могут быть выполнены только во время определённого события для достижения наилучших результатов, например, отображение загрузочного спиннера перед подготовкой или переопределение пар анимации перед сменой содержимого.
astro:before-preparation
Заголовок раздела astro:before-preparation
Добавлено в:
astro@3.6.0
Событие, которое возникает в начале фазы подготовки, после начала навигации (например, после того, как пользователь перешёл по ссылке), но до загрузки контента.
Это событие используется:
- Выполнение действий до начала загрузки, например, показ спиннера загрузки.
- Чтобы изменить загрузку, например, загрузить содержимое, заданное в шаблоне, а не из внешнего URL.
- Чтобы изменить
направление
навигации (обычно либовперёд
, либоназад
) для пользовательской анимации.
Вот пример использования события astro:before-preparation
для загрузки спиннера до загрузки контента и его остановки сразу после загрузки. Обратите внимание, что использование обратного вызова загрузчика таким образом позволяет выполнять код асинхронно.
<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
Заголовок раздела astro:after-preparation
Добавлено в:
astro@3.6.0
Событие, которое срабатывает в конце фазы подготовки, после того как содержимое новой страницы было загружено и разобрано в документ. Это событие происходит перед фазой перехода к просмотру.
В этом примере используется событие astro:before-preparation
для запуска индикатора загрузки и событие astro:after-preparation
для его остановки:
<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>
Это более простой вариант загрузки спиннера, чем пример, показанный выше: если весь код слушателя может быть выполнен синхронно, нет необходимости подключаться к обратному вызову загрузчика.
astro:before-swap
Заголовок раздела astro:before-swap
Добавлено в:
astro@3.6.0
Событие, которое срабатывает перед тем, как новый документ (который заполняется во время фазы подготовки) заменит текущий документ. Это событие происходит внутри перехода, когда пользователь всё ещё видит снимок старой страницы.
Это событие можно использовать для внесения изменений до того, как произойдет подмена. Свойство newDocument
этого события представляет входящий документ. Вот пример того, как обеспечить перенос предпочтений светлого или тёмного режима браузера в localStorage
на новую страницу:
<script is:inline> function setDarkMode(document) { let theme = localStorage.darkMode ? 'dark' : 'light'; document.documentElement.dataset.theme = theme; }
setDarkMode(document);
document.addEventListener('astro:before-swap', ev => { // Передайте входящий документ, чтобы установить для него тему setDarkMode(ev.newDocument); });</script>
Событие astro:before-swap
также может быть использовано для изменения реализации подкачки. Реализация подкачки по умолчанию различает содержимое заголовка, перемещает постоянные элементы из старого документа в newDocument
, а затем заменяет весь body
телом нового документа.
На этом этапе жизненного цикла вы можете определить свою собственную реализацию подкачки, например, диффундировать всё содержимое существующего документа (что делают некоторые другие маршрутизаторы):
<script is:inline> document.addEventListener('astro:before-swap', ev => { ev.swap = () => { diff(document, ev.newDocument); }; });</script>
Создание пользовательской функции замены
Заголовок раздела Создание пользовательской функции замены
Добавлено в:
astro@4.15.0
Объект swapFunctions
из модуля astro:transitions/client
предоставляет пять вспомогательных функций, которые обрабатывают специфические задачи, связанные с заменой, включая управление атрибутами документа, элементами страницы и выполнением скриптов. Эти функции можно использовать напрямую для определения пользовательской реализации замены.
Следующий пример демонстрирует, как использовать эти функции для воссоздания встроенной реализации замены Astro:
<script> import { swapFunctions } from "astro:transitions/client";
// заменяет `window.document` на `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(); }
event.swap = () => mySwap(event.newDocument);<script>
Пользовательские реализации замены могут начинаться с этого шаблона и добавлять или заменять отдельные шаги пользовательской логикой по мере необходимости.
astro:after-swap
Заголовок раздела astro:after-swapСобытие, которое срабатывает сразу после того, как новая страница заменит старую. Можно прослушать это событие на document
и запустить действия, которые произойдут перед отрисовкой элементов DOM новой страницы и запуском скриптов.
Это событие, прослушиваемое на исходящей странице, полезно для передачи и восстановления любого состояния DOM, которое должно быть перенесено на новую страницу.
Это последний момент в жизненном цикле, когда ещё безопасно, например, добавить имя класса тёмного режима (<html class="dark-mode">
), хотя вы можете захотеть сделать это в более раннем событии.
Событие astro:after-swap
происходит сразу после обновления истории браузера и установки позиции прокрутки.
Поэтому одним из вариантов использования этого события является отмена восстановления прокрутки по умолчанию для навигации по истории. В следующем примере для каждой навигации горизонтальная и вертикальная прокрутка устанавливается в левый верхний угол страницы.
document.addEventListener("astro:after-swap", () => window.scrollTo({ left: 0, top: 0, behavior: "instant" }),);
astro:page-load
Заголовок раздела astro:page-loadСобытие, которое срабатывает в конце навигации по странице, после того как новая страница становится видимой для пользователя и загружаются блокирующие стили и скрипты. Вы можете прослушать это событие на document
.
Компонент <ClientRouter />
вызывает это событие как при начальном переходе по странице с предварительной отрисовкой, так и при любом последующем переходе, как вперёд, так и назад.
Можно использовать это событие для запуска кода при каждой навигации по странице или только единожды:
<script> document.addEventListener('astro:page-load', () => { // Это выполняется при первой загрузке страницы и после каждой навигации. setupStuff(); // например, добавление слушателей событий });</script>
Доступность
Заголовок раздела ДоступностьВключение маршрутизации на стороне клиента и анимирование переходов между страницами сопряжены с проблемами доступности, и Astro стремится сделать сайты с поддержкой View Transitions максимально доступными по умолчанию.
Объявление о маршруте
Заголовок раздела Объявление о маршруте
Добавлено в:
astro@3.2.0
Компонент <ClientRouter />
включает в себя анонс маршрута для навигации по странице во время маршрутизации на стороне клиента. Для этого не требуется никаких настроек или действий.
Вспомогательные технологии дают посетителям понять, что страница изменилась, объявляя после навигации новый заголовок страницы. При использовании маршрутизации на стороне сервера с традиционным полностраничным обновлением браузера это происходит по умолчанию после загрузки новой страницы. При маршрутизации на стороне клиента это действие выполняет компонент <ClientRouter/>
.
Чтобы добавить анонс маршрута в маршрутизацию на стороне клиента, компонент добавляет элемент на новую страницу с атрибутом aria-live
, установленным на assertive
. Это указывает вспомогательным технологиям на необходимость немедленного объявления. Для определения текста объявления компонент также проверяет наличие следующих пунктов (в порядке приоритета):
- Заголовок
<title>
, если он существует. - Первый
<h1>
, который он найдет. - Имя страницы.
Мы настоятельно рекомендуем всегда включать <title>
в каждую страницу для обеспечения доступности.
prefers-reduced-motion
Заголовок раздела prefers-reduced-motionКомпонент Astro <ClientRouter />
включает медиазапрос CSS, который отключает все анимации переходов, включая анимацию возврата, при обнаружении параметра prefer-reduced-motion
. Вместо этого браузер просто поменяет местами элементы DOM без анимации.