Библиотека Tabbable в JavaScript предназначена для определения элементов веб-страницы, на которые можно перемещаться с помощью клавиши Tab. Она анализирует DOM и возвращает список элементов, которые считаются “фокусируемыми”. Ключевая особенность — корректная работа даже с нестандартными элементами, скрытыми блоками или элементами с нестандартными атрибутами.
Базовый метод библиотеки позволяет получить массив элементов, доступных для табуляции:
import tabbable from 'tabbable';
const focusableElements = tabbable(document.body);
console.log(focusableElements);
Метод учитывает следующие критерии:
display: none и не
visibility: hidden).disabled.<input>, <button>,
<a href>, <textarea>,
<select> и элементы с
tabindex >= 0).Tabbable предоставляет возможность расширенной настройки, позволяя определить собственные правила выбора фокусируемых элементов. Это особенно важно для сложных интерфейсов, где стандартные критерии не подходят.
Можно передать функцию, которая будет определять, следует ли включать элемент в список:
const focusable = tabbable(document.body, {
filter: element => element.tagName !== 'INPUT' || element.type !== 'hidden'
});
В этом примере исключаются скрытые поля ввода, даже если у них
tabindex установлен.
Для интерфейсов с множественными секциями удобно разделять элементы на группы. Tabbable позволяет создавать иерархические фильтры, где сначала выбираются родительские контейнеры, а затем фокусируемые элементы внутри них:
const sections = document.querySelectorAll('.section');
sections.forEach(section => {
const focusables = tabbable(section, {
filter: element => !element.classList.contains('skip')
});
console.log(focusables);
});
Такой подход позволяет контролировать локальную табуляцию внутри модальных окон, виджетов или сложных форм.
tabindexTabindex является ключевым инструментом кастомизации. Он позволяет упорядочивать фокусируемые элементы произвольно, независимо от их положения в DOM:
tabindex="0" — стандартный порядок табуляции.tabindex="-1" — элемент исключается из
последовательности табуляции, но доступен программно.tabindex="n" (n > 0) — задает конкретную позицию в
последовательности.Tabbable учитывает tabindex при построении списка и
позволяет реализовать сложные схемы навигации, например
при управлении с клавиатуры большим набором интерактивных элементов.
По умолчанию Tabbable сортирует элементы в порядке их появления в DOM. Для создания нестандартного порядка можно использовать кастомные функции сортировки:
const focusables = tabbable(document.body).sort((a, b) => {
return a.dataset.priority - b.dataset.priority;
});
Эта стратегия позволяет сортировать элементы на основе
пользовательских атрибутов (data-priority) или других
критериев.
В современных SPA часто встречаются вложенные компоненты, например модальные окна, аккордеоны, панели с вкладками. Для корректной табуляции важно:
Пример циклической навигации:
const modal = document.querySelector('.modal');
const focusables = tabbable(modal);
modal.addEventListener('keydown', e => {
if (e.key === 'Tab') {
const first = focusables[0];
const last = focusables[focusables.length - 1];
if (e.shiftKey && document.activeElement === first) {
last.focus();
e.preventDefault();
} else if (!e.shiftKey && document.activeElement === last) {
first.focus();
e.preventDefault();
}
}
});
Для сложных интерфейсов часто необходимо исключать
определённые элементы из табуляции, например декоративные
кнопки или элементы управления виджетами, которые не должны отвлекать
пользователя. Tabbable позволяет задавать селекторы через
filter или динамически исключать элементы на основе
состояния:
const focusables = tabbable(document.body, {
filter: el => !el.classList.contains('no-tab')
});
tabindex для контроля порядка
фокусировки в сложных интерфейсах.Tabbable обеспечивает гибкую и надёжную основу для управления клавиатурной навигацией, позволяя реализовывать как стандартные, так и сложные пользовательские схемы табуляции.