Перейти к содержимому

Параметры ссылок

В SvelteKit для навигации между маршрутами приложения используются обычные элементы <a> (а не специальные компоненты вроде <Link> из фреймворка). Если пользователь кликает по ссылке, href которой принадлежит вашему приложению (а не ведёт, например, на внешний сайт), SvelteKit выполнит навигацию на новую страницу: импортирует её код и вызовет все необходимые функции load для загрузки данных.

Вы можете настраивать поведение ссылок с помощью атрибутов data-sveltekit-*. Эти атрибуты можно применять как непосредственно к элементу <a>, так и к любому его родительскому элементу.

Те же опции работают и для элементов <form> с атрибутом method="GET".

Ещё до того, как браузер зафиксирует клик пользователя по ссылке, можно заметить, что курсор завис над ней (на десктопе) или произошло событие touchstart / mousedown (на мобильных устройствах). В обоих случаях можно с высокой вероятностью предположить, что вскоре произойдёт событие click.

SvelteKit может использовать эту информацию, чтобы заранее начать загрузку кода страницы и данных — это даёт дополнительные сотни миллисекунд, которые часто становятся разницей между «тормозным» и «молниеносным» интерфейсом.

Управлять этим поведением можно с помощью атрибута data-sveltekit-preload-data. Он принимает одно из двух значений:

  • "hover" — предзагрузка начинается, когда курсор мыши останавливается над ссылкой. На мобильных устройствах предзагрузка запускается по событию touchstart
  • "tap" — предзагрузка начинается сразу после регистрации события touchstart или mousedown

В шаблоне проекта по умолчанию в файле src/app.html на элементе <body> уже установлен атрибут data-sveltekit-preload-data="hover", поэтому все ссылки в приложении предзагружаются при наведении курсора:

<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>

Иногда вызов load при наведении курсора на ссылку может быть нежелательным — либо потому, что это часто приводит к ложным срабатываниям (наведение не всегда заканчивается кликом), либо потому, что данные обновляются очень быстро и небольшая задержка может привести к отображению устаревшей информации.

В таких случаях можно указать значение "tap", при котором SvelteKit будет вызывать load только тогда, когда пользователь действительно коснётся или кликнет по ссылке:

<a data-sveltekit-preload-data="tap" href="/stonks">
Получить текущие значения стонков
</a>

Данные никогда не будут предзагружаться, если пользователь выбрал режим экономии трафика, то есть если navigator.connection.saveData равно true.

Даже в случаях, когда вы не хотите предзагружать данные для ссылки, может быть полезно предзагрузить сам код. Атрибут data-sveltekit-preload-code работает аналогично data-sveltekit-preload-data, но принимает одно из четырёх значений, расположенных по убыванию «агрессивности» предзагрузки:

  • "eager" — ссылки предзагружаются сразу же
  • "viewport" — ссылки предзагружаются, как только попадают в область видимости (viewport)
  • "hover" — как и выше, но предзагружается только код
  • "tap" — как и выше, но предзагружается только код

Обратите внимание: значения viewport и eager применяются только к ссылкам, которые присутствуют в DOM сразу после навигации. Если ссылка добавляется позже (например, внутри блока {#if ...}), она не будет предзагружаться до тех пор, пока не сработает событие hover или tap. Это сделано для избежания проблем с производительностью из-за слишком агрессивного наблюдения за изменениями в DOM.

Как и в случае с data-sveltekit-preload-data, этот атрибут игнорируется, если пользователь включил режим экономии трафика.

Иногда требуется указать SvelteKit, чтобы он не обрабатывал ссылку самостоятельно, а позволил браузеру обработать её обычным образом. Добавление атрибута data-sveltekit-reload к ссылке…

<a data-sveltekit-reload href="/path">Путь</a>

…приведёт к полной перезагрузке страницы при клике по ссылке.

Ссылки с атрибутом rel="external" будут обрабатываться точно так же. Кроме того, они будут игнорироваться во время предварительного рендеринга.

Иногда вы не хотите, чтобы навигация создавала новую запись в истории сессии браузера. Добавление атрибута data-sveltekit-replacestate к ссылке…

<a data-sveltekit-replacestate href="/path">Путь</a>

…будет заменять текущую запись в history, а не создавать новую с помощью pushState, когда по ссылке кликают.

Иногда вы не хотите, чтобы фокус сбрасывался после навигации. Например, у вас может быть форма поиска, которая отправляется по мере ввода текста пользователем, и вы хотите, чтобы фокус оставался на поле ввода. Добавление атрибута data-sveltekit-keepfocus к такому элементу…

<form data-sveltekit-keepfocus>
<input type="text" name="query">
</form>

…приведёт к тому, что текущий элемент в фокусе сохранит фокус после навигации. В общем случае избегайте использования этого атрибута на ссылках, поскольку в фокусе окажется сам тег <a> (а не ранее сфокусированный элемент), и пользователи экранных читалок и других вспомогательных технологий часто ожидают, что фокус будет перемещён после навигации. Также используйте этот атрибут только на элементах, которые всё ещё существуют после навигации. Если элемент исчезает, фокус пользователя будет потерян, что создаст запутывающий опыт для пользователей вспомогательных технологий.

При навигации по внутренним ссылкам SvelteKit повторяет поведение браузера по умолчанию: он перемещает позицию прокрутки в точку 0,0, чтобы пользователь оказался в самом верхнем левом углу страницы (если только ссылка не содержит #hash — в этом случае прокрутка происходит к элементу с соответствующим ID).

В некоторых случаях вы можете захотеть отключить это поведение. Добавление атрибута data-sveltekit-noscroll к ссылке…

<a href="path" data-sveltekit-noscroll>Путь</a>

…приведёт к тому, что прокрутка не будет выполняться после клика по ссылке.

Чтобы отключить любую из этих опций внутри элемента, где они были ранее включены, используйте значение "false":

<div data-sveltekit-preload-data>
<!-- эти ссылки будут предзагружаться -->
<a href="/a">a</a>
<a href="/b">b</a>
<a href="/c">c</a>
<div data-sveltekit-preload-data="false">
<!-- эти ссылки НЕ будут предзагружаться -->
<a href="/d">d</a>
<a href="/e">e</a>
<a href="/f">f</a>
</div>
</div>

Чтобы применить атрибут к элементу условно, сделайте так:

<div data-sveltekit-preload-data={condition ? 'hover' : false}>