ally.js — это мощная библиотека для управления
доступностью веб-приложений, ориентированная на взаимодействие с
клавиатурой, фокусом и элементами ARIA. Она обеспечивает единый
интерфейс для проверки и манипуляции состоянием доступности элементов в
DOM, устраняя различия между браузерами.
В основе работы с ally.js лежит понятие
фокусируемого элемента. Библиотека предоставляет
функции для поиска элементов, доступных для фокусировки:
ally.query.firstTabbable(document.body);
ally.query.lastTabbable(document.body);
ally.query.focusable(document.body);
firstTabbable — возвращает первый элемент, на который
можно перейти с помощью клавиши Tab.lastTabbable — последний фокусируемый элемент.focusable — массив всех элементов, доступных для
фокуса.Эти методы учитывают скрытые элементы, элементы с
display: none и visibility: hidden, а также
элементы с tabindex="-1".
Для программного управления фокусом используются функции
focus и nextFocus:
ally.focus(element);
ally.nextFocus();
focus — переводит фокус на указанный элемент, учитывая
браузерные особенности.nextFocus — позволяет перемещаться по таб-индексу
вперед или назад, обеспечивая доступность навигации для клавиатуры.ally.js позволяет проверять элементы на доступность и
корректное использование ARIA-атрибутов:
ally.query.matches(document.getElementById('myButton'), ':focusable');
ally.test.focus(element);
matches проверяет, соответствует ли элемент заданным
критериям (например, фокусируемый или видимый).test.focus возвращает объект с информацией о состоянии
фокуса и возможных препятствиях.Для работы с ARIA ally.js предоставляет методы для
безопасного чтения и изменения атрибутов:
ally.attribute.get(element, 'aria-hidden');
ally.attribute.set(element, 'aria-hidden', 'true');
ally.attribute.remove(element, 'aria-hidden');
get — чтение текущего значения атрибута.set — установка нового значения.remove — удаление атрибута из элемента.Эти методы гарантируют корректную работу с DOM, предотвращая ошибки,
которые могут возникать при прямой манипуляции через
setAttribute.
ally.js позволяет отслеживать изменения состояния фокуса
и доступности через событийный механизм:
const disposer = ally.when.key('Tab', () => {
console.log('Tab pressed');
});
disposer.discard(); // Отписка от события
ally.when.key — позволяет реагировать на нажатия
определённых клавиш.discard — удаляет привязку события, предотвращая утечки
памяти.Для создания модальных окон или панелей, где фокус должен оставаться внутри определённого контейнера, используется механизм trapFocus:
const trap = ally.trap.focus({
context: document.getElementById('modal')
});
// отключение ограничителя
trap.disengage();
context — контейнер, внутри которого ограничивается
фокус.disengage — возвращает обычное поведение фокуса для
всей страницы.Для обеспечения качества доступности на этапах непрерывной интеграции
(CI) ally.js может использоваться в автоматизированных
тестах:
Пример использования в Jest:
import ally from 'ally.js';
test('Кнопка фокусируется', () => {
document.body.innerHTML = '<button id="btn">Click</button>';
const button = document.getElementById('btn');
expect(ally.query.firstTabbable(document.body)).toBe(button);
});
Пример в Cypress для проверки модального окна:
cy.get('#modal').within(() => {
cy.get(':focusable').first().focus().should('have.focus');
cy.tab();
cy.get(':focusable').last().should('have.focus');
});
ally.js поддерживает расширения через плагин-подобные
подходы, позволяя интегрировать кастомные правила доступности,
например:
ally.js для управления
фокусом вместо прямого изменения tabindex.ally.js превращает сложную задачу обеспечения
доступности в управляемый и предсказуемый процесс, что делает её
незаменимым инструментом для современных фронтенд-приложений.