Библиотека ally.js предоставляет расширенные
инструменты для управления фокусом на элементах страницы, что критично
для доступности и улучшения пользовательского опыта. В отличие от
стандартного HTML-атрибута autofocus, ally.js позволяет
программно управлять фокусом, учитывать скрытые или временно недоступные
элементы, а также контролировать поведение при навигации через
клавиатуру.
Ключевой объект для работы с фокусом — ally. Основные
методы:
ally.query.focusable(container) — возвращает массив
всех элементов внутри container, которые могут получать
фокус. Это удобно для создания кастомных модальных окон или форм.ally.query.firstTabbable(container) — находит первый
фокусируемый элемент, доступный для табуляции.ally.query.lastTabbable(container) — аналогично, но для
последнего элемента.Эти методы учитывают видимость элемента, наличие
tabindex="-1" и другие атрибуты, влияющие на фокус.
Частая задача UX — автоматический фокус на интерактивном элементе при открытии модального окна. Ally.js позволяет реализовать это безопасно и предсказуемо:
const modal = document.querySelector('.modal');
modal.addEventListener('open', () => {
const firstInput = ally.query.firstTabbable(modal);
if (firstInput) {
firstInput.focus();
}
});
Особенности:
Ally.js предоставляет утилиты для управления фокусом при перемещении между элементами:
ally.focus.trap(container) — активирует «ловушку
фокуса», ограничивая навигацию внутри контейнера (например, модального
окна). Это предотвращает случайное перемещение фокуса за пределы
модалки.ally.focus.focusFirstTabbable(container) и
ally.focus.focusLastTabbable(container) — позволяют
программно устанавливать фокус на первый или последний доступный
элемент. Используется для циклической навигации через клавишу Tab.Пример реализации ловушки фокуса:
const modal = document.querySelector('.modal');
const trap = ally.focus.trap(modal);
// Отключение ловушки при закрытии
modal.addEventListener('close', () => trap.disengage());
Ключевые моменты:
Для сложных интерфейсов с динамическими компонентами важно корректно управлять автофокусом при изменении DOM. Ally.js учитывает следующие ситуации:
Элементы появляются после AJAX-запроса.
Используется ally.query.firstTabbable(newContainer) после
добавления элементов в DOM.
Элементы временно недоступны. Можно проверять
доступность через ally.query.focusable(container) и
выбирать подходящий элемент для фокуса.
Управление порядком табуляции. Ally.js учитывает
атрибуты tabindex, скрытые элементы и role. Это
предотвращает “провал фокуса” на недоступные элементы.
Пример динамического автофокуса:
const formSection = document.querySelector('#dynamic-section');
function focusDynamicInput() {
const input = ally.query.firstTabbable(formSection);
if (input) input.focus();
}
// После загрузки нового контента
document.addEventListener('sectionLoaded', focusDynamicInput);
Ally.js не ограничивается только модальными окнами:
tabindex и роли
(role="dialog", role="tabpanel"), чтобы
поддерживать стандарты доступности.Ally.js обеспечивает высокоуровневый контроль за фокусом, позволяя создавать сложные, доступные интерфейсы без хаотичных обходов стандартного поведения браузера. Использование библиотеки улучшает UX для пользователей с клавиатурой, экранными читалками и другими ассистивными технологиями.