Библиотека ally.js предоставляет инструменты для программного управления фокусом в веб-приложениях, обеспечивая доступность интерфейса и корректную навигацию для пользователей с различными устройствами ввода. Фокус в DOM может быть управляем как программно, так и через взаимодействие пользователя с клавиатурой или мышью. Ally.js позволяет выявлять фокусируемые элементы, фильтровать их по доступности и управлять переходами между ними.
Ключевое понятие — фокусируемый элемент. Это любой
элемент, на который может быть установлен фокус через
tabindex, встроенные интерактивные элементы
(<button>, <a>,
<input> и т. д.) или кастомные компоненты с
использованием скриптов. Ally.js предоставляет API для работы с такими
элементами с учётом их состояния (disabled,
hidden, aria-hidden и т. д.).
Метод ally.query.focusable() позволяет получить список
элементов, которые можно сфокусировать в текущем документе:
const focusableElements = ally.query.focusable({ context: document.body });
console.log(focusableElements);
Параметры метода:
true,
возвращаются только элементы, доступные через клавишу Tab.Пример фильтрации по CSS-классу:
const buttons = ally.query.focusable({
context: document.body,
filter: node => node.classList.contains('interactive-button')
});
Такой подход позволяет строить точный список элементов для управления фокусом.
Для установки фокуса используется метод
ally.focus.element():
ally.focus.element(document.getElementById('submit-btn'));
Особенности:
display: none или visibility: hidden, при
использовании опции preventScroll.ally.focus.element(document.querySelector('.hidden-input'), { silent: true });
Метод возвращает промис, который разрешается после завершения установки фокуса, что важно для асинхронных интерфейсов и анимаций.
Ally.js предоставляет средства для контроля порядка перехода
по Tab. Метод ally.focus.next() позволяет
программно перейти к следующему фокусируемому элементу:
ally.focus.next(document.activeElement);
Параметры:
true фокус вернётся к
первому элементу после последнего.Методы ally.focus.previous() и
ally.focus.first() работают аналогично, обеспечивая полное
управление навигацией.
Для модальных окон или всплывающих панелей важно ограничить
фокус внутри контейнера. Ally.js предоставляет функцию
ally.trap.focus():
const trap = ally.trap.focus({
context: document.getElementById('modal'),
cycle: true
});
Особенности работы:
disengage() для
снятия ограничения:trap.disengage();
Такой подход предотвращает потерю фокуса за пределами модального окна и улучшает доступность интерфейса.
Ally.js учитывает элементы, которые появляются или исчезают динамически. Для корректной работы с такими элементами следует:
Пример:
document.body.appendChild(newButton);
ally.focus.element(newButton).then(() => {
console.log('Фокус установлен на динамически добавленную кнопку');
});
Ally.js учитывает атрибуты ARIA при фильтрации:
Это позволяет строить интерфейсы, соответствующие стандартам WCAG, без дополнительных проверок.
Типичные сценарии применения ally.js:
element.focus() при необходимости.Ally.js предоставляет гибкую систему для программного управления фокусом, делая интерфейсы доступными и предсказуемыми, упрощая реализацию сложной логики навигации без ручного обхода DOM.