Переопределение поведения по умолчанию

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

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


Переопределение поведения по умолчанию

По умолчанию Focus-trap обрабатывает следующие сценарии:

  1. Автоматический фокус на первый элемент при активации.
  2. Перевод фокуса на последний интерактивный элемент при цикличном переходе через Tab/Shift+Tab.
  3. Опциональное возвращение фокуса на элемент, вызвавший активацию.

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


Настройка фокуса при активации

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

const trap = createFocusTrap('#modal', {
  initialFocus: '#modal-input'
});
trap.activate();
  • Если initialFocus не указан, фокус устанавливается на первый доступный интерактивный элемент.
  • Можно использовать функцию для динамического выбора элемента:
const trap = createFocusTrap('#modal', {
  initialFocus: () => document.querySelector('.special-button')
});

Это позволяет выбирать элемент на основе текущего состояния интерфейса.


Игнорирование некоторых элементов

Иногда требуется, чтобы определённые элементы внутри ловушки не участвовали в цикле фокуса. Для этого используется опция allowOutsideClick и метод setReturnFocus совместно с кастомной фильтрацией:

const trap = createFocusTrap('#modal', {
  onActivate: () => console.log('Trap активирован'),
  tabbableOptions: {
    displayCheck: 'none'  // исключает скрытые элементы
  }
});

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


Переопределение поведения клавиши Escape

Focus-trap по умолчанию деактивируется при нажатии Escape. Для изменения этого поведения используется опция onDeactivate и escapeDeactivates:

const trap = createFocusTrap('#modal', {
  escapeDeactivates: false, // блокировка стандартного закрытия
  onKeyDown: (event) => {
    if (event.key === 'Escape') {
      console.log('Escape нажат, но ловушка активна');
      // Дополнительная логика вместо закрытия
    }
  }
});

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


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

Возврат фокуса на элемент, вызвавший активацию, выполняется через опцию setReturnFocus. Можно указать кастомный элемент или полностью блокировать возврат:

const trap = createFocusTrap('#modal', {
  setReturnFocus: false // фокус не возвращается
});

Если требуется перенаправление фокуса на другой элемент после деактивации:

const trap = createFocusTrap('#modal', {
  setReturnFocus: '#next-button'
});

Работа с асинхронным контентом

Для элементов, которые появляются динамически (например, после AJAX-запроса), важно переопределить initialFocus через функцию, чтобы фокус устанавливался только после рендеринга:

const trap = createFocusTrap('#modal', {
  initialFocus: () => document.querySelector('.dynamic-input')
});

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


Настройка цикличного перехода

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

const trap = createFocusTrap('#modal', {
  fallbackFocus: '#modal' // фокус возвращается на контейнер
});

Это полезно для нестандартных интерфейсов, где нет явного первого или последнего элемента.


Расширение событий и логики

Focus-trap предоставляет хуки:

  • onActivate — вызывается при активации ловушки.
  • onDeactivate — вызывается при деактивации.
  • onPostActivate / onPostDeactivate — позволяют работать после установки или снятия фокуса.

Пример:

const trap = createFocusTrap('#modal', {
  onActivate: () => console.log('Активировано'),
  onDeactivate: () => console.log('Деактивировано')
});

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


Вывод

Переопределение поведения Focus-trap сводится к правильной настройке опций при инициализации: initialFocus, tabbableOptions, escapeDeactivates, setReturnFocus и хуков событий. Это обеспечивает гибкое управление фокусом в динамических и интерактивных интерфейсах, позволяя строить сложные модальные окна, панели и диалоговые компоненты с безопасной и предсказуемой клавиатурной навигацией.