Обработка инерционного скролла

Headroom.js — это лёгкая JavaScript-библиотека для управления видимостью шапки сайта при прокрутке. Она позволяет скрывать или показывать элемент в зависимости от направления скролла, что особенно полезно для мобильных интерфейсов и длинных страниц. Одним из ключевых аспектов является корректная обработка инерционного скролла, когда браузер продолжает движение контента после прекращения активного скроллинга пользователем.


Подключение и инициализация Headroom.js

Для начала необходимо подключить библиотеку через CDN или npm:

<script src="https://unpkg.com/headroom.js@0.12.0/dist/headroom.min.js"></script>

Инициализация базового экземпляра выглядит так:

var header = document.querySelector("header");
var headroom = new Headroom(header, {
    tolerance: 5,
    offset: 50,
    classes: {
        initial: "headroom",
        pinned: "headroom--pinned",
        unpinned: "headroom--unpinned",
        top: "headroom--top",
        notTop: "headroom--not-top",
        bottom: "headroom--bottom",
        notBottom: "headroom--not-bottom"
    }
});
headroom.init();
  • tolerance — минимальное смещение, которое необходимо для срабатывания события.
  • offset — расстояние от верхней границы страницы, после которого активируется скрытие/показ шапки.
  • classes — CSS-классы для различных состояний элемента.

Обработка инерционного скролла

Браузеры на мобильных устройствах и некоторых десктопах используют инерционный скролл, когда страница продолжает скролл после отпускания пальца или мыши. В стандартной конфигурации Headroom.js может некорректно реагировать на этот эффект, вызывая преждевременное или запоздалое скрытие шапки.

Для решения этой проблемы используется комбинация расширенной настройки tolerance и периодической проверки позиции скролла.

var lastScrollY = window.scrollY;
var ticking = false;

function updateHeadroom() {
    headroom.update(window.scrollY);
    ticking = false;
}

window.addEventListener('scroll', function() {
    if (!ticking) {
        window.requestAnimationFrame(updateHeadroom);
        ticking = true;
    }
});
  • Использование requestAnimationFrame позволяет сгладить обработку скролла и синхронизировать обновления состояния с перерисовкой страницы.
  • ticking предотвращает многократные вызовы функции при высокой скорости скролла.

Настройка параметров tolerance для инерционного скролла

Для корректной работы с инерционным скроллом важно подобрать правильное значение tolerance. Если значение слишком маленькое, шапка будет дергаться при каждом пикселе прокрутки. Слишком большое — шапка будет медленно реагировать.

var headroom = new Headroom(header, {
    tolerance: {
        up: 20,    // порог смещения при скролле вверх
        down: 5    // порог смещения при скролле вниз
    },
    offset: 50
});
headroom.init();
  • tolerance.up регулирует чувствительность к скроллу вверх.
  • tolerance.down регулирует чувствительность к скроллу вниз.
  • Для мобильных устройств рекомендуется увеличить значение up, чтобы инерционный скролл не прятал шапку преждевременно.

Отслеживание конца инерции

В некоторых случаях необходимо отслеживать момент окончания инерционного скролла, чтобы выполнить дополнительную логику (например, закрепление шапки или запуск анимации).

let scrollTimeout;

window.addEventListener('scroll', () => {
    clearTimeout(scrollTimeout);
    scrollTimeout = setTimeout(() => {
        headroom.pin();  // фиксируем шапку после завершения прокрутки
    }, 150); // время ожидания окончания скролла в мс
});
  • setTimeout с очисткой предыдущего таймера позволяет определить момент, когда страница перестала двигаться.
  • Значение 150–200 мс подходит для большинства мобильных устройств.

Совместимость с плавным скроллом

Если на странице используется CSS-свойство scroll-behavior: smooth, инерционный скролл может быть длиннее и с меньшими шагами. В таких случаях необходимо увеличить tolerance и время ожидания в таймере окончания прокрутки:

tolerance: { up: 25, down: 10 }
scrollTimeout = setTimeout(() => { headroom.pin(); }, 250);

Это позволяет избежать дергания шапки и обеспечивает плавное появление/скрытие элемента.


Подключение к кастомным событиям

Headroom.js предоставляет события pin и unpin, которые можно использовать для создания дополнительных эффектов при инерционном скролле:

header.addEventListener('headroom-pin', () => {
    console.log('Шапка закреплена');
});

header.addEventListener('headroom-unpin', () => {
    console.log('Шапка скрыта');
});

Эти события срабатывают только после применения всех фильтров tolerance и offset, что делает их надёжными для отслеживания состояния шапки при инерционном скролле.


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

  • Использовать requestAnimationFrame вместо обычного обработчика scroll для экономии ресурсов.
  • Настраивать tolerance и offset под целевое устройство (мобильное/десктопное).
  • Проверять взаимодействие с CSS-анимациями, чтобы избежать конфликта между transition и состояниями Headroom.
  • Для сложных интерфейсов можно комбинировать Headroom.js с библиотеками типа GSAP для плавного скрытия и появления элементов.

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