Навигация с клавиатуры является ключевым аспектом доступности веб-приложений. В контексте SvelteKit UI libraries управление фокусом и обработка событий клавиатуры обеспечивают удобный пользовательский интерфейс без необходимости использования мыши. В SvelteKit компоненты можно сделать полностью доступными с помощью встроенных событий и специальных атрибутов.
tabindex Позволяет контролировать
порядок фокусировки элементов.
tabindex="0" – элемент доступен в обычном порядке
табуляции.tabindex="-1" – элемент доступен для фокусировки
программно, но пропускается при обычной навигации.tabindex="n" (n > 0) – задаёт конкретный порядок
фокусировки, но использование чисел больше 0 не рекомендуется для
динамических интерфейсов из-за сложности поддержки.autofocus Автоматически ставит
фокус на элемент при рендеринге компонента. Используется для форм или
модальных окон.
SvelteKit позволяет обрабатывать события клавиатуры напрямую через
стандартные DOM-события: keydown, keyup,
keypress. На практике чаще всего используют
keydown, так как оно срабатывает до
действия браузера и позволяет предотвратить стандартное поведение.
<script>
function handleKeyDown(event) {
if (event.key === "Enter") {
console.log("Enter нажата");
} else if (event.key === "ArrowDown") {
event.preventDefault();
console.log("Перемещение вниз");
}
}
</script>
<input on:keydown={handleKeyDown} />
Большинство библиотек UI для SvelteKit (например, Svelte Material UI, Skeleton UI) предоставляют компоненты с встроенной поддержкой навигации с клавиатуры:
Enter и Space.ArrowUp/ArrowDown) и выбор элементов клавишей
Enter.Пример кастомного меню с клавиатурной навигацией:
<script>
import { onMount } from 'svelte';
let items = ["Пункт 1", "Пункт 2", "Пункт 3"];
let currentIndex = 0;
let menu;
function handleKey(event) {
if (event.key === "ArrowDown") {
currentIndex = (currentIndex + 1) % items.length;
} else if (event.key === "ArrowUp") {
currentIndex = (currentIndex - 1 + items.length) % items.length;
} else if (event.key === "Enter") {
console.log(`Выбран: ${items[currentIndex]}`);
}
}
onMount(() => {
menu.focus();
});
</script>
<ul bind:this={menu} tabindex="0" on:keydown={handleKey}>
{#each items as item, i}
<li class:selected={i === currentIndex}>{item}</li>
{/each}
</ul>
<style>
li.selected {
background-color: #007acc;
color: white;
}
</style>
В SvelteKit важно корректно управлять фокусом при изменении DOM, особенно в интерактивных компонентах:
bind:this позволяет ссылаться на
элемент и программно устанавливать фокус.tick() из svelte
используется для ожидания рендера перед установкой фокуса.<script>
import { tick } from 'svelte';
let input;
async function focusInput() {
await tick();
input.focus();
}
</script>
<input bind:this={input} />
<button on:click={focusInput}>Фокус на поле</button>
Для соблюдения ARIA-стандартов рекомендуется использовать атрибуты:
aria-selected для выделенных элементов.aria-expanded для раскрывающихся списков.role="menu" и role="menuitem" для меню и
пунктов меню.Это позволяет вспомогательным технологиям (экранным читалкам) корректно интерпретировать состояние интерфейса и обеспечивать навигацию с клавиатуры.
SvelteKit UI libs часто предоставляют утилиты для управления фокусом между компонентами:
focusable – возвращает массив всех
интерактивных элементов.focusNext / focusPrev –
перемещает фокус по порядку.Пример с кастомной формой:
<script>
import { focusNext, focusPrev } from 'sveltekit-ui-utils';
function handleTab(event) {
if (event.key === "Tab" && !event.shiftKey) {
event.preventDefault();
focusNext(event.target);
} else if (event.key === "Tab" && event.shiftKey) {
event.preventDefault();
focusPrev(event.target);
}
}
</script>
<form on:keydown={handleTab}>
<input placeholder="Имя" />
<input placeholder="Email" />
<button type="submit">Отправить</button>
</form>
Эти практики обеспечивают доступность, согласованность и предсказуемость интерфейса при работе с клавиатурой в SvelteKit UI.