Создание первой ловушки фокуса

Библиотека Focus-trap предназначена для управления фокусом в веб-приложениях. Она позволяет ограничить область фокуса внутри конкретного контейнера, например модального окна, выпадающего меню или панели настройки. Основная задача — предотвращение случайного ухода фокуса за пределы интерактивного элемента и обеспечение корректной навигации с клавиатуры.

Фокусировка управляется с помощью двух ключевых понятий: активация ловушки и деактивация ловушки. При активации все элементы, доступные для фокуса, замыкаются внутри контейнера. При попытке перейти за пределы последнего элемента фокус возвращается к первому, создавая цикл.

import { createFocusTrap } from 'focus-trap';

const modal = document.querySelector('#modal');
const focusTrap = createFocusTrap(modal);

В приведённом примере создаётся базовая ловушка фокуса для элемента с идентификатором modal. Пока ловушка активна, навигация с помощью клавиши Tab или Shift+Tab будет ограничена этим контейнером.


Активация и деактивация ловушки

Активация производится вызовом метода activate, деактивация — deactivate. Это обеспечивает явное управление состоянием фокуса.

// Активация
focusTrap.activate();

// Деактивация
focusTrap.deactivate();

Можно автоматически активировать ловушку при открытии модального окна и деактивировать при его закрытии. Это гарантирует, что фокус не покинет контейнер, пока окно открыто, и возвращается к элементу, который его инициировал, после закрытия.


Настройка начального фокуса

По умолчанию Focus-trap устанавливает фокус на первый интерактивный элемент внутри контейнера. Для более точного контроля можно использовать опцию initialFocus:

const focusTrap = createFocusTrap(modal, {
  initialFocus: '#close-button'
});

Здесь фокус будет установлен на кнопку закрытия модального окна сразу после активации ловушки. Можно передавать как селектор, так и функцию, возвращающую DOM-элемент.


Управление возвращением фокуса

Опция returnFocusOnDeactivate отвечает за возвращение фокуса к элементу, который был активен до активации ловушки. Это важно для поддержания логики клавиатурной навигации:

const focusTrap = createFocusTrap(modal, {
  returnFocusOnDeactivate: true
});

Если эта опция отключена, фокус останется на последнем элементе внутри контейнера после деактивации.


Дополнительные параметры конфигурации

  • escapeDeactivates: при true ловушка отключается при нажатии клавиши Escape.
  • clickOutsideDeactivates: при true клики вне контейнера также отключают ловушку.
  • allowOutsideClick: позволяет разрешить клики по элементам за пределами ловушки, не деактивируя её.
const focusTrap = createFocusTrap(modal, {
  escapeDeactivates: true,
  clickOutsideDeactivates: true
});

Эти параметры делают использование ловушки гибким, адаптируя её поведение под конкретные сценарии взаимодействия.


Интерактивные элементы и вложенные ловушки

Ловушка фокуса учитывает только интерактивные элементы: <button>, <a>, <input>, <textarea>, <select> и элементы с tabindex >= 0. Для сложных интерфейсов с несколькими модальными окнами можно создавать вложенные ловушки, но необходимо тщательно контролировать активацию и деактивацию, чтобы избежать конфликта фокусов.


Примеры практического применения

  1. Модальные окна — предотвращение ухода фокуса за пределы диалога.
  2. Боковые панели и аккордеоны — блокировка навигации, пока панель открыта.
  3. Формы с шагами — фокус цикличен внутри текущего шага, исключая элементы следующего.

Отладка и тестирование

Для проверки работы ловушки можно использовать клавишу Tab и убедиться, что фокус корректно замыкается внутри контейнера. При сложных интерфейсах удобно использовать визуальные индикаторы фокуса и консольные логи при активации и деактивации.

focusTrap.activate();
console.log('Ловушка фокуса активирована');
focusTrap.deactivate();
console.log('Ловушка фокуса деактивирована');

Это позволяет убедиться, что фокус управляется правильно, и исключить неожиданные переходы между элементами.


Focus-trap обеспечивает надёжное управление клавиатурной навигацией и является стандартным инструментом для доступного веб-разработки, особенно в интерфейсах с динамическими элементами.