Headroom.js — это библиотека, предназначенная для управления
поведением элементов при скролле страницы. В классическом варианте она
чаще используется для шапок сайта, скрывая их при прокрутке вниз и
показывая при прокрутке вверх. Однако принципы её работы можно
эффективно применять и для кастомных скроллеров внутри модальных
окон, где стандартный window.scroll не
применяется, а прокрутка происходит в отдельном контейнере.
Вместо привязки к window необходимо указать конкретный
контейнер модального окна как scrolling element.
Например:
const modal = document.querySelector('.modal');
const header = modal.querySelector('.modal-header');
const headroom = new Headroom(header, {
scroller: modal, // контейнер, за которым следим
tolerance: {
up: 5,
down: 10
},
offset: 50,
classes: {
initial: 'headroom',
pinned: 'headroom--pinned',
unpinned: 'headroom--unpinned',
top: 'headroom--top',
notTop: 'headroom--not-top'
}
});
headroom.init();
Ключевые моменты:
scroller — элемент, у которого происходит прокрутка. По
умолчанию Headroom слушает window.tolerance — порог чувствительности для скролла вверх
(up) и вниз (down). Позволяет избежать
“дребезга” при мелких движениях.offset — расстояние в пикселях от начала скролла до
первой реакции Headroom. Полезно, когда верхняя часть модального окна
может содержать пустое пространство или padding.classes — настраиваемые CSS-классы, обеспечивающие
плавные анимации при изменении состояния.Модальные окна часто содержат динамический контент, который может изменять высоту контейнера. Для корректной работы Headroom нужно учитывать пересчет размеров:
const resizeObserver = new ResizeObserver(() => {
headroom.destroy();
headroom.init();
});
resizeObserver.observe(modal);
ResizeObserver следит за изменением размеров
контейнера.Для модальных окон важно, чтобы скроллер был визуально плавным. Headroom генерирует классы, которые можно использовать в CSS для переходов:
.headroom {
transition: transform 0.3s ease-in-out;
}
.headroom--pinned {
transform: translateY(0);
}
.headroom--unpinned {
transform: translateY(-100%);
}
transform работает лучше, чем top или
margin, так как использует аппаратное ускорение.transition определяет скорость анимации и кривую
ускорения, что особенно важно для модальных окон с ограниченной
высотой.Headroom должен корректно реагировать на открытие и закрытие модального окна. Это можно реализовать через события:
modal.addEventListener('open', () => {
headroom.init();
});
modal.addEventListener('close', () => {
headroom.destroy();
});
init и destroy гарантируют, что библиотека
не будет реагировать на скролл, когда модальное окно скрыто.Если внутри модального окна есть внутренние скролл-области (например, список сообщений), Headroom можно применить к каждой области отдельно:
const innerScroll = modal.querySelector('.messages');
const innerHeadroom = new Headroom(innerScroll.querySelector('.inner-header'), { scroller: innerScroll });
innerHeadroom.init();
tolerance и offset может
отличаться от внешнего скролла для большей отзывчивости.Для модальных окон с большим количеством контента следует учитывать частоту обновления скролл-событий:
const throttledScroll = _.throttle(() => headroom.update(), 50);
modal.addEventListener('scroll', throttledScroll);
throttle (например, из lodash) для
уменьшения числа вызовов update.Headroom.js позволяет добавлять кастомные коллбэки при смене состояния:
const headroom = new Headroom(header, {
onPin: () => console.log('Pinned'),
onUnpin: () => console.log('Unpinned')
});
scroller
вместо window.transform и
transition.Эта схема обеспечивает стабильную, отзывчивую и визуально приятную работу заголовков и элементов интерфейса внутри модальных окон, полностью используя возможности Headroom.js для кастомного скроллинга.