Библиотека ally.js предназначена для управления доступностью веб-приложений, в частности, для контроля фокуса при изменении состояния интерфейса или маршрутизации. Она обеспечивает инструментарием для безопасного управления фокусом, предотвращения “потерянного” фокуса и упрощает работу с элементами DOM, которые становятся видимыми или скрытыми динамически.
В основе ally.js лежат три ключевых направления:
tabbable и focusable).focus,
blur).ally.js предоставляет функции для выявления элементов, которые можно фокусировать:
import * as ally from 'ally.js';
// Получение всех фокусируемых элементов внутри контейнера
const focusableElements = ally.query.focusable({
context: document.getElementById('modal')
});
// Получение только тех элементов, которые можно достичь с помощью Tab
const tabbableElements = ally.query.tabbable({
context: document.getElementById('modal')
});
Особенности:
disabled
элементы.Правильное различие между этими типами критично при динамическом управлении интерфейсом: для модальных окон обычно используются только tabbable-элементы, чтобы фокус не переходил на невидимые части страницы.
Для управления фокусом при изменении маршрута используется метод
focus(). Он позволяет программно установить фокус на
элемент и гарантирует доступность:
ally.focus({
element: document.getElementById('first-input'),
preventScroll: true
});
Параметры функции focus:
element — целевой DOM-элемент.preventScroll — фокус устанавливается без прокрутки
страницы.ignoreVisibility — позволяет фокусировать элементы,
которые скрыты с помощью CSS.Использование этих опций важно при роутинге: часто новая страница или компонент появляется динамически, и нужно предотвратить резкое смещение окна или установку фокуса на невидимый элемент.
При смене маршрута (например, в SPA на React или Vue) фокус должен логически переходить на новый ключевой элемент. ally.js предоставляет функции для безопасного переноса фокуса:
// После смены маршрута
const mainContent = document.getElementById('main-content');
if (mainContent) {
ally.focus({
element: mainContent,
preventScroll: true
});
}
Практические рекомендации:
trap.tab), чтобы Tab и Shift+Tab
циклировали внутри окна.ally.js поддерживает трап фокуса для модальных окон, что предотвращает уход фокуса за пределы окна:
import { trap } from 'ally.js';
const modal = document.getElementById('modal');
const trapInstance = trap.focus(modal);
// После закрытия модального окна
trapInstance.disengage();
Особенности:
returnFocus).Это критично для SPA, где компоненты создаются и уничтожаются без перезагрузки страницы.
ally.js позволяет следить за изменениями DOM, чтобы автоматически корректировать фокус:
ally.when.visible({
filter: '#dynamic-content',
callback: (elements) => {
ally.focus({ element: elements[0] });
}
});
Это особенно полезно при роутинге и загрузке асинхронного контента, когда элементы появляются на странице спустя некоторое время.
В SPA роутерах, таких как React Router или Vue Router, ally.js интегрируется с жизненным циклом маршрута:
router.afterEach(() => {
const mainHeading = document.querySelector('h1');
if (mainHeading) {
ally.focus({ element: mainHeading });
}
});
Рекомендации:
h1) или на
контейнер основного контента.preventScroll: true, чтобы избежать
неожиданных прокруток.ally.js также предоставляет инструменты для проверки доступности фокуса:
const issues = ally.check.focus({ context: document.body });
console.log(issues);
check.focus выявляет элементы, на которые невозможно
поставить фокус.focusable или
tabbable).focus() и
trap.focus().when.visible).Эта последовательность обеспечивает стабильное управление фокусом, улучшает доступность и предотвращает потерю взаимодействия при роутинге и динамических изменениях интерфейса.