При реализации плавной прокрутки страницы с помощью библиотеки Smooth Scroll важно учитывать управление фокусом, особенно для обеспечения доступности веб-приложений и корректного взаимодействия с клавиатурой. Smooth Scroll отвечает за анимацию перемещения к целевому элементу, но поведение фокуса по умолчанию не всегда соответствует стандартам доступности.
Smooth Scroll позволяет прокручивать страницу к определённому
элементу через привязку к ссылкам с хешами (#id) или
программно с помощью метода animateScroll. Однако простое
смещение окна не меняет текущий фокус, что может вызвать проблемы для
пользователей с клавиатурой или экранными читалками.
Пример базового использования:
const scroll = new SmoothScroll('a[href*="#"]', {
speed: 600,
offset: 0,
clip: true,
updateURL: true
});
// Программный вызов прокрутки
const target = document.querySelector('#section2');
scroll.animateScroll(target);
В этом примере элемент #section2 будет виден после
анимации, но фокус останется на документе, а не на
целевом элементе.
Для правильного управления фокусом после завершения прокрутки следует
использовать коллбэк after:
scroll.animateScroll(target, null, {
speed: 600,
offset: 0,
updateURL: true,
after: function(anchor, toggle) {
anchor.setAttribute('tabindex', '-1'); // Делаем элемент фокусируемым, если это не интерактивный элемент
anchor.focus({ preventScroll: true }); // Устанавливаем фокус без смещения страницы
}
});
Ключевые моменты:
tabindex="-1" позволяет программно установить
фокус на элемент, который обычно не фокусируемый.preventScroll: true предотвращает повторное
смещение страницы при установке фокуса.after срабатывает после завершения
анимации, что гарантирует корректное положение элемента на
экране.Если целевой элемент уже интерактивен (например, button,
input, a), дополнительный
tabindex не нужен. В этом случае достаточно
вызвать focus:
scroll.animateScroll(document.querySelector('#submitBtn'), null, {
after: function(anchor) {
anchor.focus();
}
});
Это позволяет сохранить естественное поведение клавиатуры и корректно активировать элементы с точки зрения доступности.
Smooth Scroll может обновлять URL и автоматически обрабатывать ссылки с хешами. Для сохранения управления фокусом рекомендуется:
preventDefault() для предотвращения мгновенной
прокрутки.Пример:
document.querySelectorAll('a[href^="#"]').forEach(link => {
link.addEventListener('click', function(e) {
e.preventDefault();
const target = document.querySelector(this.getAttribute('href'));
scroll.animateScroll(target, this, {
after: function(anchor) {
anchor.setAttribute('tabindex', '-1');
anchor.focus({ preventScroll: true });
}
});
});
});
Если контент на странице подгружается динамически, элемент может отсутствовать в DOM в момент инициализации Smooth Scroll. В этом случае нужно:
document.querySelector.animateScroll только после полной загрузки
контента.tabindex и фокус через коллбэк after.Пример:
const dynamicTarget = document.querySelector('#dynamicSection');
if(dynamicTarget) {
scroll.animateScroll(dynamicTarget, null, {
after: (anchor) => {
anchor.setAttribute('tabindex', '-1');
anchor.focus({ preventScroll: true });
}
});
}
Для элементов, на которые устанавливается фокус после прокрутки, важно соблюдать ARIA-рекомендации:
h2,
h3), добавление role="region" с
aria-labelledby помогает экранным читалкам определить
контекст.aria-live
для уведомления о появлении нового контента после прокрутки.Пример:
<section id="section2" role="region" aria-labelledby="section2-title">
<h2 id="section2-title">Раздел 2</h2>
...
</section>
scroll.animateScroll(document.querySelector('#section2'), null, {
after: (anchor) => {
anchor.setAttribute('tabindex', '-1');
anchor.focus({ preventScroll: true });
}
});
after для
установки фокуса после завершения анимации.tabindex="-1" для
нефокусируемых элементов перед вызовом focus.focus.Эта практика позволяет обеспечить плавную прокрутку и поддерживать корректное поведение фокуса, что критично для доступности и удобства взаимодействия с веб-страницей.