Обработка фокуса элементов

Smooth Scroll в JavaScript позволяет не только анимированно прокручивать страницу к определённым элементам, но и управлять фокусом на этих элементах, что особенно важно для доступности (accessibility) и интерактивных интерфейсов. Работа с фокусом гарантирует, что пользователь после прокрутки попадёт непосредственно на нужный элемент, а клавиатурная навигация останется логичной.

Основы установки фокуса

После завершения анимации прокрутки можно программно установить фокус на элемент с помощью метода focus(). Например:

const target = document.querySelector('#section2');
target.scrollIntoView({ beh * avior: 'smooth' });
target.focus({ preventScroll: true });

Ключевой момент: использование опции preventScroll: true предотвращает повторную прокрутку при установке фокуса. Без неё браузер может мгновенно подскроллить страницу, нарушив плавность анимации.

Управление tabindex

Для элементов, которые по умолчанию не могут получать фокус (например, <div> или <span>), необходимо явно добавить атрибут tabindex. Наиболее безопасный подход:

<div id="section2" tabindex="-1">Контент секции 2</div>

tabindex="-1" делает элемент доступным для фокуса через JavaScript, но не добавляет его в последовательность клавиатурной навигации. Это идеальный вариант для целей Smooth Scroll.

Интеграция с библиотекой Smooth Scroll

Если используется сторонняя библиотека Smooth Scroll, например, cferdinandi/smooth-scroll, фокус можно устанавливать в колбэке после завершения анимации. Пример:

const scroll = new SmoothScroll('a[href*="#"]', {
    speed: 500,
    offset: 20,
    clip: true
});

document.querySelectorAll('a[href*="#"]').forEach(link => {
    link.addEventListener('click', function(event) {
        const target = document.querySelector(this.getAttribute('href'));
        scroll.animateScroll(target, this, {
            after: () => {
                target.setAttribute('tabindex', '-1');
                target.focus({ preventScroll: true });
            }
        });
    });
});

Важно: атрибут tabindex устанавливается непосредственно перед фокусом. После завершения анимации его можно оставить или удалять, если нужно сохранить чистоту DOM.

Обработка фокуса для динамических элементов

Для элементов, которые создаются динамически (например, через AJAX или React), порядок действий следующий:

  1. После вставки элемента в DOM установить tabindex="-1".
  2. Дождаться завершения анимации прокрутки.
  3. Установить фокус через focus({ preventScroll: true }).
function scrollToDynamicElement(elementId) {
    const element = document.getElementById(elementId);
    element.setAttribute('tabindex', '-1');
    element.scrollIntoView({ beh * avior: 'smooth' });
    element.addEventListener('transitionend', () => {
        element.focus({ preventScroll: true });
    }, { once: true });
}

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

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

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

  • aria-labelledby — указывает на заголовок элемента.
  • aria-live="polite" — уведомляет пользователей скринридеров о появлении нового контента без резкой смены фокуса.
  • role="region" — определяет логическую область для навигации.

Пример:

<div id="section2" tabindex="-1" role="region" aria-labelledby="section2-title">
  <h2 id="section2-title">Секция 2</h2>
  <p>Контент секции.</p>
</div>

Сохранение исходного положения фокуса

При использовании Smooth Scroll важно сохранить возможность возвращения к предыдущему фокусу, особенно для форм или интерактивных списков. Для этого можно сохранять активный элемент перед прокруткой:

const previousFocus = document.activeElement;
target.scrollIntoView({ beh * avior: 'smooth' });
target.focus({ preventScroll: true });
// при необходимости позже
previousFocus.focus();

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

Рекомендации по оптимизации UX

  • Не перемещать фокус слишком часто; комбинировать визуальную прокрутку с логической фокусировкой.
  • Для длинных страниц использовать плавную прокрутку с небольшим отступом (offset), чтобы заголовки не прилипали к верхней границе окна.
  • Всегда тестировать фокус с клавиатурой и скринридерами, чтобы убедиться, что Smooth Scroll не нарушает доступность.

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