Focus management

Focus management в веб-разработке играет ключевую роль в создании доступных и удобных интерфейсов. Фреймворк Fresh предоставляет современные инструменты для работы с фокусом, позволяя управлять поведением элементов при взаимодействии пользователя с клавиатурой и другими устройствами ввода. Рассмотрим основные подходы и возможности.


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

В Fresh управление фокусом строится на стандартных механизмах браузера, расширяемых через JSX-компоненты и обработчики событий. Основные методы включают:

  • Атрибут tabindex Элемент с tabindex="0" становится доступным для навигации с клавиатуры, а отрицательные значения (tabindex="-1") исключают элемент из последовательности табуляции, но оставляют возможность программно установить фокус.

  • Метод focus() Позволяет программно установить фокус на элемент. В Fresh его удобно использовать в сочетании с useEffect для управления фокусом после рендера компонента.

/** @jsx h */
import { h } from "preact";
import { useEffect, useRef } from "preact/hooks";

export default function InputFocus() {
  const inputRef = useRef<HTMLInputElement>(null);

  useEffect(() => {
    inputRef.current?.focus();
  }, []);

  return <input ref={inputRef} placeholder="Фокус установлен автоматически" />;
}
  • Метод blur() Убирает фокус с элемента, что полезно для управления переходами между полями формы или после выполнения определённых действий.

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

Fresh поддерживает декларативную работу с фокусом через хуки и свойства компонентов. Основные подходы:

  1. Использование ref ref позволяет ссылаться на DOM-элемент и управлять фокусом программно. Особенно важно при работе с динамическими формами и модальными окнами.

  2. Фокус после рендера Использование useEffect или useLayoutEffect обеспечивает корректное управление фокусом после того, как компонент полностью отрендерен, предотвращая ошибки при попытке установить фокус на ещё не существующий элемент.

useEffect(() => {
  if (modalOpen) {
    modalRef.current?.focus();
  }
}, [modalOpen]);
  1. Переход между элементами формы Реализация логики автоперехода фокуса после ввода данных в поле (onInput или onChange) повышает удобство работы с формами.

Доступность и ARIA

Focus management в Fresh тесно связан с доступностью. Для обеспечения корректной работы с экранными читалками используются атрибуты ARIA:

  • aria-labelledby и aria-describedby помогают связать элемент с заголовками и подсказками.
  • aria-hidden="true" исключает элементы из навигации для пользователей экранных читалок.
  • role="dialog" и управление фокусом внутри модальных окон позволяют пользователям клавиатуры оставаться внутри диалога до закрытия.

Пример модального окна с управлением фокусом:

export default function Modal({ open, onClose }: { open: boolean; onClose: () => void }) {
  const modalRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (open) {
      modalRef.current?.focus();
    }
  }, [open]);

  return open ? (
    <div
      ref={modalRef}
      tabIndex={-1}
      role="dialog"
      aria-modal="true"
      onKeyD own={(e) => e.key === "Escape" && onClose()}
    >
      <h2>Модальное окно</h2>
      <button onCl ick={onClose}>Закрыть</button>
    </div>
  ) : null;
}

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

В интерактивных списках (например, при добавлении/удалении элементов) важно корректно поддерживать последовательность фокуса:

  • После добавления нового элемента логично переводить фокус на него.
  • После удаления элемента фокус следует переносить на соседний элемент, чтобы избежать потери контекста для пользователя.
const listRef = useRef<HTMLUListElement>(null);

function handleAddItem() {
  setItems([...items, "Новый элемент"]);
  setTimeout(() => {
    const lastItem = listRef.current?.lastElementChild as HTMLElement | null;
    lastItem?.focus();
  }, 0);
}

Поддержка мобильных устройств и touch-интерфейсов

Focus management на мобильных устройствах требует особого внимания. В Fresh это учитывается через:

  • Использование событий onFocus и onBlur для адаптации интерфейса под виртуальную клавиатуру.
  • Минимизацию автоматических фокусов, чтобы не вызывать неожиданный сдвиг контента при открытии клавиатуры.

Сводка практик

  1. Использование tabindex для контроля порядка навигации.
  2. Программное управление фокусом через ref и методы focus() / blur().
  3. Использование хуков useEffect для фокусировки после рендера.
  4. Обеспечение доступности через ARIA-атрибуты и роли.
  5. Контроль фокуса в динамических списках и модальных компонентах.
  6. Адаптация поведения под мобильные устройства и touch-интерфейсы.

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