Параметр initialFocus

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

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


Форматы задания initialFocus

initialFocus может быть задан несколькими способами:

  1. CSS-селектор

    const trap = createFocusTrap('#modal', {
        initialFocus: '#modal input[name="username"]'
    });

    В этом случае библиотека ищет первый элемент внутри контейнера, соответствующий указанному селектору, и устанавливает на него фокус.

  2. DOM-элемент

    const inputElement = document.querySelector('#modal input[name="username"]');
    const trap = createFocusTrap('#modal', {
        initialFocus: inputElement
    });

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

  3. Функция

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

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


Поведение при неверной настройке

Если initialFocus:

  • не задан: библиотека попытается установить фокус на первый доступный фокусируемый элемент внутри контейнера.
  • указан элемент вне контейнера: библиотека проигнорирует настройку и фокус будет установлен на первый внутренний элемент.
  • указан несуществующий селектор: срабатывает тот же механизм fallback на первый фокусируемый элемент.

Это важно учитывать, чтобы избегать ошибок, когда элемент может ещё не быть в DOM при активации trap.


Взаимодействие с другими параметрами

  • fallbackFocus Работает как запасной вариант, если initialFocus недоступен. Рекомендуется всегда задавать fallbackFocus, чтобы гарантировать корректное поведение:

    const trap = createFocusTrap('#modal', {
        initialFocus: '#modal input[name="username"]',
        fallbackFocus: '#modal button.close'
    });
  • onActivate и onPostActivate Параметры обратного вызова могут использоваться для дополнительной логики после установки initialFocus, например, для валидации или прокрутки к элементу:

    const trap = createFocusTrap('#modal', {
        initialFocus: '#modal input[name="username"]',
        onPostActivate: () => console.log('Фокус установлен')
    });

Практические рекомендации

  1. Указывать конкретный элемент или селектор — это повышает предсказуемость поведения trap.
  2. Использовать функцию для динамически создаваемых интерфейсов.
  3. Совместно с fallbackFocus гарантирует корректную доступность даже при неожиданных изменениях DOM.
  4. Не указывать элементы вне контейнера, чтобы избежать конфликтов и непредсказуемого поведения.
  5. Проверять наличие элемента перед активацией trap, особенно если он создаётся асинхронно.

Примеры использования

Модальное окно с полем ввода:

const modalTrap = createFocusTrap('#modal', {
    initialFocus: '#modal input:first-of-type',
    fallbackFocus: '#modal button.close'
});

document.querySelector('#openModal').addEventListener('click', () => {
    modalTrap.activate();
});

Динамический контент:

const dynamicTrap = createFocusTrap('#dynamicContainer', {
    initialFocus: () => document.querySelector('#dynamicContainer input.dynamic'),
    fallbackFocus: '#dynamicContainer button.default'
});

dynamicTrap.activate();

Множественные интерактивные элементы:

const complexTrap = createFocusTrap('#formContainer', {
    initialFocus: '#formContainer select.priority',
    fallbackFocus: '#formContainer button.submit'
});

complexTrap.activate();

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