Библиотека Tabbable предназначена для определения
элементов на веб-странице, которые могут получать фокус при навигации с
помощью клавиши Tab. Она предоставляет методы для
проверки доступности элементов и упрощает управление последовательностью
фокусировки в сложных интерфейсах. Библиотека совместима с современными
браузерами и учитывает особенности скрытых элементов, элементов с
атрибутами disabled и tabindex.
Основной экспорт библиотеки — функция tabbable, которая
принимает DOM-элемент или документ и возвращает массив элементов,
доступных для табуляции.
import { tabbable } from 'tabbable';
const focusableElements = tabbable(document.body);
console.log(focusableElements);
Результатом является отсортированный список элементов, соответствующий порядку, в котором пользователь будет переходить по ним с помощью клавиши Tab.
tabbable(node, options)node — контейнер, внутри которого производится поиск фокусируемых элементов.
options — объект настроек:
includeContainer (boolean) — включает контейнер в
список, если он сам является фокусируемым.getShadowRoot (function) — позволяет обрабатывать
элементы внутри Shadow DOM.Возвращает массив элементов, доступных для табуляции. Элементы
сортируются по логическому DOM-порядку и учитывают атрибуты
tabindex и disabled.
isTabbable(element)Проверяет, может ли конкретный элемент получать фокус с помощью Tab.
Возвращает true или false.
import { isTabbable } from 'tabbable';
const button = document.querySelector('button');
console.log(isTabbable(button)); // true или false
focusable(element)Определяет, может ли элемент получить фокус вообще (не только через
Tab, но и программно). Отличается от isTabbable тем, что
учитывает все способы фокусировки, включая скриптовые вызовы
element.focus().
Библиотека корректно работает с элементами:
tabindex.getShadowRoot, позволяющую рекурсивно находить фокусируемые
элементы внутри теневого дерева.display: none или visibility: hidden
игнорируются, что предотвращает случайное включение невидимых кнопок в
порядок табуляции.Пример рекурсивного поиска в Shadow DOM:
const focusableInShadow = tabbable(document.querySelector('my-component'), {
getShadowRoot: el => el.shadowRoot
});
tabindexЭлементы с tabindex управляют порядком перемещения
фокуса:
tabindex="0" — элемент включен в естественный порядок
DOM.tabindex="-1" — элемент фокусируемый программно, но
пропускается при навигации Tab.tabindex="1+" — приоритетное место в последовательности
фокуса, элементы с меньшим числом получают фокус раньше.Библиотека сортирует элементы с учетом этих значений, что позволяет создавать интерфейсы с нестандартной навигацией без ручного управления фокусом.
Для сложных интерфейсов важно видеть порядок табуляции, чтобы выявлять скрытые проблемы с фокусом. Tabbable не имеет встроенного логгера, но интеграция с консолью JavaScript или библиотеками логирования позволяет отслеживать фокусируемые элементы на любом этапе.
Пример простого логирования:
const elements = tabbable(document.body);
elements.forEach((el, index) => {
console.log(`${index + 1}: <${el.tagName.toLowerCase()}>`, el);
});
Дополнительные практики для отладки:
.tab-debug:focus {
outline: 2px solid red !important;
}
tabbable(document.body).forEach(el => el.classList.add('tab-debug'));
Это позволяет визуально проверять, совпадает ли порядок элементов с ожидаемым.
Unit-тесты и e2e-тесты можно строить на базе Tabbable, проверяя доступность ключевых интерфейсных компонентов:
import { tabbable } from 'tabbable';
import { expect } from 'chai';
const focusableElements = tabbable(document.querySelector('#form'));
expect(focusableElements[0].tagName.toLowerCase()).to.equal('input');
Использование Tabbable в тестах помогает автоматизировать проверку
доступности и выявлять элементы с неправильным
tabindex.
tabbable для формирования списка
фокусируемых элементов перед программной манипуляцией
фокусом.isTabbable и focusable можно
создавать надежные проверки доступности элементов.tabindex > 0, чтобы избежать
неожиданных нарушений логики навигации.Эта методика обеспечивает контролируемую навигацию по интерфейсу, позволяет поддерживать доступность для пользователей с клавиатурой и предотвращает ошибки фокусировки в сложных SPA и компонентах с динамическим DOM.