Управление фокусом в слоях

Unpoly предоставляет мощный механизм для управления фокусом элементов при работе с многослойными интерфейсами. Важно понимать, что каждый слой (layer) в Unpoly — это отдельный контекст, и взаимодействие с фокусом элементов в этих слоях требует осознанного подхода.


Слои и их влияние на фокус

Каждый слой в Unpoly имеет собственное дерево DOM, но может находиться поверх других слоев. Основные типы слоев:

  • Основной слой (up.layer.content) — базовый контент страницы.
  • Всплывающие слои (up.layer.popup) — модальные окна или временные панели.
  • Фоновые слои (up.layer.background) — используются для фоновых процессов без прямого взаимодействия пользователя.

При открытии нового слоя Unpoly автоматически управляет фокусом следующим образом:

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

Это поведение предотвращает потерю контекста для пользователя и обеспечивает доступность интерфейса.


Методы управления фокусом

Unpoly предоставляет несколько методов и событий для управления фокусом:

  1. up.focus(element)

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

    up.focus('#search-input');
  2. События фокусировки слоев

    • up:layer:opened — срабатывает после открытия слоя. Можно использовать для установки фокуса на определённый элемент.
    • up:layer:closed — срабатывает после закрытия слоя, удобно для возврата фокуса на инициирующий элемент.

    Пример:

    up.on('up:layer:opened', function(event) {
      if (event.layer.type === 'popup') {
        up.focus(event.layer.element.querySelector('input:first-of-type'));
      }
    });
  3. Атрибут up-autofocus

    Можно использовать HTML-атрибут на элементе, чтобы указать, что фокус должен автоматически устанавливать именно этот элемент при открытии слоя:

    <input type="text" up-autofocus>

    Unpoly автоматически переносит фокус на этот элемент при рендеринге слоя.


Управление фокусом в сложных слоях

В сложных интерфейсах с несколькими вложенными слоями нужно учитывать следующие моменты:

  • Фокус блокируется только для верхнего слоя. Элементы нижнего слоя не могут получить фокус, пока верхний слой активен.
  • Табуляция ограничена текущим слоем, что предотвращает случайное перемещение фокуса за пределы модального окна.
  • Возврат фокуса должен быть явно настроен при закрытии слоя, особенно если инициирующий элемент изменился или был удалён.

Пример ручного управления:

const triggerButton = document.querySelector('#open-popup');

up.on('up:layer:opened', function(event) {
  if (event.layer.type === 'popup') {
    const input = event.layer.element.querySelector('input:first-of-type');
    up.focus(input);
  }
});

up.on('up:layer:closed', function(event) {
  triggerButton.focus();
});

Фокус и динамическое обновление содержимого

При загрузке нового контента через Unpoly (up.render) важно учитывать фокус:

  • Фокус на новом элементе: если новый фрагмент содержит элемент с up-autofocus, фокус перемещается на него.
  • Фокус на инициирующем элементе: если новый фрагмент не содержит элементов для фокуса, фокус остаётся на том элементе, который вызвал обновление.
  • Предотвращение неожиданных перемещений фокуса: можно передать опцию focus: false при рендере:
up.render('#comments', '/comments', { focus: false });

Тонкие моменты и рекомендации

  • Не использовать автоматический фокус на скрытых элементах: это приведёт к неожиданным эффектам.
  • Всегда проверять наличие элемента перед установкой фокуса.
  • Для улучшения доступности интерфейса рекомендовано использовать up-autofocus совместно с событиями открытия слоев.
  • Вложенные слои требуют явного контроля фокуса, чтобы пользователь не потерял контекст при закрытии всплывающих окон.

Фокус в Unpoly — это не просто установка курсора на элемент. Это контекстный механизм, позволяющий управлять вниманием пользователя, сохранять доступность интерфейса и корректно работать с множественными слоями одновременно. Правильное использование up.focus, up-autofocus и событий открытия/закрытия слоев обеспечивает интуитивное и безопасное поведение при взаимодействии с динамическим интерфейсом.