Автоматическое закрытие

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

Focus-trap предоставляет методы и опции, которые позволяют настроить автоматическое завершение работы:

  • onDeactivate — коллбек, вызываемый при деактивации ловушки. Важно использовать его для очистки ресурсов, снятия слушателей событий и закрытия модальных окон.
  • escapeDeactivates — булевое значение. Если true, нажатие клавиши Escape автоматически деактивирует ловушку.
  • clickOutsideDeactivates — булевое значение или функция. Позволяет закрывать модальное окно при клике вне области ловушки. Функция предоставляет доступ к событию клика для более точной логики.

Пример настройки ловушки с автоматическим закрытием через Escape и клик вне элемента:

import { createFocusTrap } from 'focus-trap';

const modalElement = document.getElementById('modal');

const trap = createFocusTrap(modalElement, {
  escapeDeactivates: true,
  clickOutsideDeactivates: true,
  onDeactivate: () => {
    modalElement.style.display = 'none';
    console.log('Модальное окно закрыто');
  }
});

trap.activate();

Автоматическое закрытие по таймеру

В некоторых случаях требуется закрывать модальные окна через определённое время. Это реализуется сочетанием Focus-trap и setTimeout. Таймер можно запускать при активации ловушки, а при деактивации очищать его, чтобы избежать неожиданных действий после закрытия.

let autoCloseTimer;

const trapWithTimer = createFocusTrap(modalElement, {
  onActivate: () => {
    autoCloseTimer = setTimeout(() => {
      trapWithTimer.deactivate();
    }, 5000); // Закрытие через 5 секунд
  },
  onDeactivate: () => {
    clearTimeout(autoCloseTimer);
    modalElement.style.display = 'none';
  }
});

trapWithTimer.activate();

Ключевой момент: необходимо очищать таймер при деактивации ловушки, иначе закрытие может произойти повторно или в неподходящий момент.

Динамическая активация и деактивация

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

function openModal(modalId) {
  const modal = document.getElementById(modalId);
  modal.style.display = 'block';

  const dynamicTrap = createFocusTrap(modal, {
    escapeDeactivates: true,
    onDeactivate: () => {
      modal.style.display = 'none';
    }
  });

  dynamicTrap.activate();
}

Управление взаимодействием с внешними событиями

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

Пример закрытия модального окна при клике вне его области:

createFocusTrap(modalElement, {
  clickOutsideDeactivates: (event) => {
    return !modalElement.contains(event.target);
  },
  onDeactivate: () => {
    modalElement.style.display = 'none';
  }
}).activate();

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

Взаимодействие с анимацией

Автоматическое закрытие должно учитывать анимации появления и скрытия. Деактивация ловушки до завершения анимации может привести к потере фокуса или визуальной «рваности». Лучшей практикой является запуск trap.deactivate() после окончания CSS-анимации или события transitionend.

modalElement.addEventListener('transitionend', () => {
  if (modalElement.classList.contains('closing')) {
    trap.deactivate();
  }
});

Обработка ошибок и исключений

При автоматическом закрытии важно предусмотреть сценарии, когда элемент уже удалён из DOM или ловушка деактивирована повторно. Focus-trap безопасно обрабатывает повторные деактивации, но стоит избегать прямого обращения к элементам, которых больше нет, чтобы предотвратить ошибки типа Cannot read property of null.


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