Библиотека ally.js предназначена для упрощения работы с
доступностью веб-интерфейсов. Один из ключевых модулей —
ally.query.tabbable — позволяет получать список элементов
страницы, на которые пользователь может перейти с помощью клавиши
Tab, учитывая все нюансы видимости, атрибутов и
ARIA-стандартов.
ally.query.tabbableally.query.tabbable используется для:
Tab может быть нарушена.Модуль возвращает массив DOM-элементов, которые соответствуют критериям tabbable:
display !== none,
visibility !== hidden, отсутствие
aria-hidden="true" на родителях).disabled не установлен).ally.query.tabbableБазовый синтаксис:
import tabbable from 'ally.js/query/tabbable';
const elements = tabbable({
context: document.body,
includeContext: false,
});
Параметры:
context (DOM-элемент, по
умолчанию document) Определяет корневой узел, внутри
которого происходит поиск tabbable-элементов.
includeContext (boolean, по
умолчанию false) Если true, корневой
элемент включается в результат, если он сам tabbable.
filter (функция,
необязательная) Позволяет дополнительно фильтровать результаты.
Возвращает true, если элемент должен остаться.
Пример с фильтром:
const interactiveButtons = tabbable({
context: document.querySelector('#container'),
filter: (element) => element.tagName === 'BUTTON'
});
Элементы, которые считаются tabbable:
<a> с атрибутом href.<button>, <input>,
<select>, <textarea> (если не
disabled).tabindex="0" или положительным
tabindex.contenteditable="true".Элементы исключаются из списка, если:
display: none или
visibility: hidden.aria-hidden="true" через
родительский элемент.disabled.tabindex равен отрицательному значению (например,
tabindex="-1").tabindexally.query.tabbable корректно обрабатывает
положительные, нулевые и отрицательные значения
tabindex:
tabindex="0": элемент tabbable, следует естественному
порядку DOM.tabindex > 0: элемент tabbable, приоритет
фокусировки выше стандартного порядка.tabindex < 0: элемент не tabbable, но может быть
программно сфокусирован через JS.При работе с большим DOM-деревом рекомендуется:
context.filter для сокращения количества
проверяемых элементов.Пример эффективного поиска:
const visibleInputs = tabbable({
context: document.querySelector('.form-section'),
filter: (el) => el.tagName === 'INPUT' && el.offsetParent !== null
});
const modalTabbable = tabbable({ context: modalElement });
modalElement.addEventListener('keydown', (event) => {
if (event.key === 'Tab') {
// логика циклического обхода tabbable-элементов
}
});
Динамически добавляемые элементы После
добавления новых интерактивных элементов нужно повторно вызывать
tabbable, чтобы обновить список доступных
элементов.
Пользовательские виджеты Создание кастомных
селектов, вкладок и аккордеонов требует управления фокусом.
Использование ally.query.tabbable позволяет корректно
определить порядок перехода по клавише Tab.
opacity: 0 или за
пределами видимой области; учитывает только видимость через CSS и
ARIA.ally.jsally.query.focusable: возвращает элементы, которые
могут быть сфокусированы программно. Различие: tabbable учитывает только
элементы, доступные через Tab.ally.maintain.tabFocus: помогает удерживать фокус
внутри контейнера, используя результаты tabbable.ally.style.focusVisible: стилизует элементы при
получении фокуса, совместимо с tabbable-элементами.context для ограничения области
поиска и повышения производительности.filter для специфических интерактивных
элементов.ally.query.tabbable обеспечивает точное определение
клавиатурной навигации, что критично для создания доступных
веб-приложений, особенно в динамически изменяемых интерфейсах и при
работе с модальными компонентами.