Библиотека ally.js предоставляет набор инструментов для управления фокусом и обеспечения доступности веб-интерфейсов с помощью клавиатуры. Основной принцип работы заключается в контроле фокуса элементов DOM и обеспечении корректного порядка навигации, что особенно важно для пользователей, использующих клавиатуру или вспомогательные технологии.
Клавиатурная навигация опирается на несколько ключевых понятий:
<a>,
<button>, <input> и элементы с
tabindex).Tab.Метод ally.query.focusable() позволяет получить список
всех элементов, доступных для фокусировки. Он учитывает:
button,
input, select, textarea,
a[href]).tabindex >= 0.Пример использования:
const focusableElements = ally.query.focusable({ context: document });
focusableElements.forEach(el => console.log(el));
Параметр context задает контейнер, в пределах которого
ищутся элементы. Это позволяет ограничить поиск определенной секцией
страницы.
Библиотека предоставляет методы для установки, получения и управления фокусом:
ally.focus() — переносит фокус на указанный
элемент.ally.has.focus() — проверяет, находится ли элемент в
фокусе.ally.next.focus() / ally.previous.focus()
— позволяет программно перемещать фокус вперед или назад в порядке
табуляции.Пример установки фокуса на первый элемент формы:
const firstInput = document.querySelector('form input');
ally.focus(firstInput);
Для циклической навигации по модальному окну используется комбинация
ally.next.focus() и контроля события keydown,
чтобы реализовать фокус-трап.
Фокус-трап — это техника, которая ограничивает навигацию клавиатуры внутри определенного контейнера, например, модального окна. Это предотвращает уход фокуса за пределы интерактивной области до закрытия окна.
Реализация с ally.js:
const modal = document.getElementById('modal');
function trapFocus(event) {
const focusableElements = ally.query.focusable({ context: modal });
const firstEl = focusableElements[0];
const lastEl = focusableElements[focusableElements.length - 1];
if (event.key === 'Tab') {
if (event.shiftKey) {
if (document.activeElement === firstEl) {
event.preventDefault();
lastEl.focus();
}
} else {
if (document.activeElement === lastEl) {
event.preventDefault();
firstEl.focus();
}
}
}
}
modal.addEventListener('keydown', trapFocus);
Этот код обеспечивает циклическое перемещение фокуса внутри модального окна без выхода за его пределы.
tabindexally.js позволяет динамически изменять доступность
элементов:
ally.query.tabindex() — получение элементов с
tabindex.ally.query.tabindex({ context, includeOnlyTabbable: true })
— фильтрует только доступные для клавиатуры элементы.tabindex позволяет
временно исключать элементы из навигации или включать их при
необходимости.Пример временного отключения всех ссылок на странице:
const links = ally.query.tabindex({ context: document, includeOnlyTabbable: true });
links.forEach(link => link.setAttribute('tabindex', '-1'));
Библиотека учитывает элементы, которые визуально скрыты, но остаются
фокусируемыми. С помощью опций displayCheck можно
контролировать, какие элементы считать доступными:
strict — только полностью видимые элементы.non-zero-area — элементы с ненулевой областью
отображения.none — все элементы, включая скрытые.Пример:
const visibleFocusable = ally.query.focusable({ context: document, displayCheck: 'strict' });
Для полноценной клавиатурной навигации необходимо сочетать ally.js с
событиями keydown и keyup. Часто используется
комбинация с обработкой клавиш Tab, Shift+Tab,
Enter, Space и стрелок, чтобы реализовать
пользовательские виджеты, списки, меню и аккордеоны, соответствующие
стандартам WAI-ARIA.
document.addEventListener('keydown', event => {
if (event.key === 'ArrowDown') {
ally.next.focus();
event.preventDefault();
} else if (event.key === 'ArrowUp') {
ally.previous.focus();
event.preventDefault();
}
});
ally.query.focusable().tabindex и события клавиатуры
для создания доступных интерфейсов с предсказуемым поведением.Эти инструменты позволяют реализовать надежную и стандартизированную клавиатурную навигацию, соблюдая требования доступности и улучшая взаимодействие с веб-приложениями.