Библиотека Focus-trap предназначена для управления фокусом внутри определённого DOM-элемента, ограничивая навигацию клавишами табуляции и предотвращая случайный уход фокуса за пределы контейнера. Основная цель — создание доступных интерфейсов, где модальные окна, всплывающие меню или диалоги не нарушают последовательность навигации для пользователей клавиатуры.
Focus-trap работает через привязку к DOM-элементу и управление
событиями keydown для клавиш Tab и
Shift+Tab. При активации, библиотека сохраняет текущий
фокус, перемещает его внутрь контейнера и отслеживает попытки выхода за
пределы. При деактивации фокус возвращается к исходному элементу.
Для создания trap используется функция createFocusTrap.
Она принимает селектор контейнера или сам DOM-элемент и объект
конфигурации:
import { createFocusTrap } from 'focus-trap';
const modal = document.getElementById('myModal');
const trap = createFocusTrap(modal, {
escapeDeactivates: true,
clickOutsideDeactivates: false,
allowOutsideClick: true,
fallbackFocus: modal
});
Ключевые опции:
escapeDeactivates — позволяет закрывать trap при
нажатии Escape.clickOutsideDeactivates — деактивация при клике вне
контейнера.allowOutsideClick — разрешает клики по элементам вне
trap без деактивации.fallbackFocus — элемент, который получает фокус, если
внутри контейнера нет фокусируемых элементов.Trap не активен по умолчанию; для включения используется метод
trap.activate().
Условная активация заключается в активации trap только при выполнении определённых условий, например, при открытии модального окна или при конкретном состоянии интерфейса.
const isModalOpen = false;
function toggleModal() {
if (!isModalOpen) {
modal.style.display = 'block';
trap.activate();
} else {
trap.deactivate();
modal.style.display = 'none';
}
}
Особенности условной активации:
Focus-trap позволяет динамически управлять активностью через методы:
trap.activate() — включение trap.trap.deactivate() — выключение trap.trap.updateContainerElements(newContainer) — смена
контейнера без пересоздания trap.trap.pause() / trap.unpause() — временная
приостановка без деактивации.Пример условной активации при нажатии кнопки:
document.getElementById('openBtn').addEventListener('click', () => {
trap.activate();
});
document.getElementById('closeBtn').addEventListener('click', () => {
trap.deactivate();
});
Если внутри контейнера добавляются новые фокусируемые элементы после
активации trap, библиотека автоматически учитывает их при навигации
Tab. Для сложных случаев можно использовать метод
trap.updateContainerElements:
const newModal = document.getElementById('newModal');
trap.updateContainerElements(newModal);
trap.activate();
При условной активации trap важно учитывать другие интерактивные элементы:
allowOutsideClick.fallbackFocus, чтобы избежать потери
фокуса.pause и unpause вместо полного удаления trap
для сохранения текущего состояния фокуса.Focus-trap позволяет создавать управляемые, доступные интерфейсы, где условная активация обеспечивает гибкое и безопасное управление фокусом, минимизируя ошибки навигации и улучшая пользовательский опыт на клавиатуре.