Условная активация

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

Focus-trap работает через привязку к DOM-элементу и управление событиями keydown для клавиш Tab и Shift+Tab. При активации, библиотека сохраняет текущий фокус, перемещает его внутрь контейнера и отслеживает попытки выхода за пределы. При деактивации фокус возвращается к исходному элементу.


Создание и инициализация focus trap

Для создания 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';
  }
}

Особенности условной активации:

  1. Отслеживание состояния интерфейса — важно синхронизировать состояние переменной с визуальным отображением модального окна.
  2. Избежание конфликтов с другими trap — если несколько trap могут быть активны одновременно, необходимо гарантировать, что активен только один. Используются флаги состояния или очередь активации.
  3. Фокус при активации — focus-trap автоматически фокусирует первый фокусируемый элемент внутри контейнера, но fallbackFocus обеспечивает предсказуемое поведение, если элементов нет.

Программное управление активацией

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 важно учитывать другие интерактивные элементы:

  • Всплывающие подсказки или менюшки — следует приостанавливать trap на время взаимодействия с ними.
  • Фокус вне модального окна — если нужно позволить взаимодействие с определёнными элементами вне trap, используется опция allowOutsideClick.
  • Асинхронный контент — при подгрузке элементов через AJAX или динамическое создание кнопок fallbackFocus гарантирует корректное место для фокуса.

Практические сценарии условной активации

  1. Модальные окна — активация только при открытии окна и деактивация при закрытии.
  2. Всплывающие меню — trap активируется при открытии меню и автоматически освобождает фокус при его закрытии.
  3. Диалоги подтверждения — условная активация минимизирует случайное взаимодействие с другими элементами страницы.

Советы по использованию

  • Всегда задавать fallbackFocus, чтобы избежать потери фокуса.
  • Использовать флаги состояния для контроля активации, особенно при нескольких trap на одной странице.
  • Проверять совместимость с динамически создаваемыми элементами, чтобы trap корректно реагировал на изменения DOM.
  • Для сложных интерфейсов рассматривать использование pause и unpause вместо полного удаления trap для сохранения текущего состояния фокуса.

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