Скрипты и обработка событий
Вы можете добавить интерактивность в компоненты Astro без использования UI-фреймворка (EN), такого как React, Svelte, Vue и т. д., используя стандартный HTML тег <script>
. Это позволяет отправлять JavaScript в браузер и добавлять функциональность в компоненты Astro.
Клиентские скрипты
Заголовок раздела Клиентские скриптыСкрипты могут использоваться для того, чтобы добавить обработчики событий, отправить аналитические данные, анимировать элементы и многого другого, что JavaScript может делать в Интернете.
По умолчанию Astro обрабатывает и собирает теги <script>
, добавляя поддержку импорта модулей npm, написания TypeScript и т. д.
Использование <script>
в Astro
Заголовок раздела Использование <script> в AstroВ файлы .astro
можно добавить клиентский JavaScript, добавив один (или несколько) тегов <script>
.
В этом примере добавление компонента <Hello />
на страницу приведет к выводу сообщения в консоль браузера.
Обработка скриптов
Заголовок раздела Обработка скриптовПо умолчанию теги <script>
обрабатываются Astro.
- Любые импорты будут скомпонованы, что позволит вам импортировать локальные файлы или модули Node.
- Обработанный скрипт будет вставлен в
<head>
вашей страницы с помощьюtype="module"
. - TypeScript поддерживается полностью, включая импорт файлов TypeScript.
- Если ваш компонент используется на странице несколько раз, скрипт будет добавлен в сборку и на страницу только единожды.
Атрибут type="module"
заставляет браузер воспринимать скрипт как модуль JavaScript. Это дает несколько преимуществ в плане производительности:
- Рендеринг не блокируется. Браузер продолжает обрабатывать остальную часть HTML, пока загружается скрипт модуля и его зависимости.
- Браузер ожидает обработки HTML перед выполнением модульных скриптов. Вам не нужно прослушивать событие “load”.
- Атрибуты
async
иdefer
не нужны. Модульные скрипты всегда откладываются.
Атрибут async
полезен для обычных скриптов, поскольку он не позволяет им блокировать рендеринг. Однако модульные скрипты уже имеют такое поведение. Добавление async
к модульному скрипту приведет к тому, что он будет выполняться до полной загрузки страницы. Вероятно, это не то, что вам нужно.
Отказ от обработки
Заголовок раздела Отказ от обработкиЧтобы запретить Astro обрабатывать скрипт, добавьте директиву is:inline
.
В некоторых ситуациях Astro не будет обрабатывать теги скриптов. В частности, добавление type="module"
или любого другого атрибута, кроме src
, к тегу <script>
приведет к тому, что Astro будет обрабатывать тег так, как если бы он содержал директиву is:inline
. То же самое будет справедливо, если скрипт записан в выражении JSX.
<script>
смотрите на странице справочника директив (EN).
Включение файлов javascript на страницу
Заголовок раздела Включение файлов javascript на страницуВозможно, вы захотите написать свои скрипты в виде отдельных файлов .js
/.ts
или вам понадобится сослаться на внешний скрипт на другом сервере. Вы можете сделать это, сославшись на них в атрибуте <script>
тега “src`.
Импорт локальных скриптов
Заголовок раздела Импорт локальных скриптовКогда это использовать: когда ваш скрипт находится внутри src/
.
Astro создаст, оптимизирует и добавит эти скрипты на страницу за вас, следуя своим правилам обработки скриптов.
Загрузка внешних скриптов
Заголовок раздела Загрузка внешних скриптовКогда использовать: когда ваш JavaScript-файл находится внутри public/
или на CDN.
Чтобы загрузить скрипты вне папки src/
вашего проекта, включите директиву is:inline
. Этот подход позволяет обойтись без обработки, сборки и оптимизации JavaScript, которые обеспечивает Astro, когда вы импортируете скрипты, как описано выше.
Общие шаблоны скриптов
Заголовок раздела Общие шаблоны скриптовОбработка onclick
и других событий
Заголовок раздела Обработка onclick и других событийНекоторые UI-фреймворки используют собственный синтаксис для обработки событий, например onClick={...}
(React/Preact) или @click="..."
(Vue). Astro больше следует стандартному HTML и не использует пользовательский синтаксис для событий.
Вместо этого вы можете использовать addEventListener
в теге <script>
для обработки взаимодействия с пользователем.
Если на странице имеется несколько компонентов <AlertButton />
, Astro не будет запускать скрипт несколько раз. Скрипты собираются и добавляются на страницу единожды. Использование querySelectorAll
гарантирует, что скрипт добавит обработчики событий к каждой кнопке с классом alert
, найденной на странице.
Веб-компоненты с пользовательскими элементами
Заголовок раздела Веб-компоненты с пользовательскими элементамиВы можете создавать собственные HTML-элементы с пользовательским поведением, используя стандарт Web Components. Определение пользовательского элемента в компоненте .astro
позволяет создавать интерактивные компоненты без использования библиотеки UI-фреймворка.
В этом примере мы определяем новый HTML-элемент <astro-heart>
, который отслеживает количество нажатий на кнопку сердца и обновляет <span>
актуальным значением.
Использование пользовательского элемента здесь имеет два преимущества:
-
Вместо поиска по всей странице с помощью
document.querySelector()
, вы можете использоватьthis.querySelector()
, который ищет только в пределах текущего экземпляра пользовательского элемента. Это позволяет упростить работу с дочерними элементами внутри элемента. -
Хотя
<script>
выполняется только один раз, браузер будет запускать методconstructor()
нашего пользовательского элемента каждый раз, когда найдет на странице<astro-heart>
. Это означает, что вы можете смело писать код для одного компонента, даже если собираетесь использовать этот компонент несколько раз на странице.
Передача переменных frontmatter в скрипты
Заголовок раздела Передача переменных frontmatter в скриптыВ компонентах Astro код в frontmatter между кодовым забором ---
выполняется на сервере и недоступен в браузере. Чтобы передавать переменные с сервера на клиент, нам нужен способ хранить наши переменные и затем считывать их при запуске JavaScript в браузере.
Один из способов сделать это - использовать атрибуты data-*
для хранения значений переменных в HTML-выводах. Скрипты, включая пользовательские элементы, могут считывать эти атрибуты с помощью свойства dataset
элемента, когда HTML загружается в браузере.
В этом примере компонента свойство message
хранится в атрибуте data-message
, поэтому пользовательский элемент может прочитать this.dataset.message
и получить значение этого свойства в браузере.
Теперь мы можем использовать наш компонент несколько раз, и каждый раз нас будет приветствовать разное сообщение.
Это как раз то, что Astro делает под капотом, когда вы передаете пропсы компоненту, написанному с использованием UI-фреймворка, например React! Для компонентов с директивой client:*
Astro создаёт кастомный элемент <astro-island>
с атрибутом props
, который и хранит все серверные данные в HTML.