Locomotive Scroll — это библиотека для плавного скроллинга с расширенными возможностями, включая работу с событиями и пользовательскими обработчиками. Передача данных в обработчики начинается с инициализации скроллера:
import LocomotiveScroll from 'locomotive-scroll';
const scroll = new LocomotiveScroll({
el: document.querySelector('#js-scroll'),
smooth: true,
multiplier: 1.2
});
В объекте конфигурации el указывает корневой контейнер
скролла, smooth активирует плавность, а
multiplier регулирует скорость прокрутки. После создания
экземпляра можно подписываться на события, передавая данные внутрь
обработчиков.
Locomotive Scroll предоставляет несколько типов событий:
scroll, call, enter,
leave, resize. Основная задача — передать
данные из контекста скроллера в обработчик. Это реализуется через
замыкания или передачу объекта параметров:
scroll.on('scroll', (args) => {
console.log('Позиция скролла:', args.scroll.y);
console.log('Данные элемента:', args.currentElements);
});
В этом примере args содержит ключевые свойства:
scroll: текущие координаты прокрутки (x,
y);currentElements: список активных элементов с
data-scroll атрибутами;limit: максимальное значение прокрутки;direction: направление движения (up или
down).Использование этих данных позволяет создавать динамическую анимацию, изменять стиль элементов и синхронизировать их с позицией скролла.
data-scroll-callДля более сложных сценариев Locomotive Scroll поддерживает событие
call, которое вызывается на элементах с атрибутом
data-scroll-call. В этот обработчик можно передавать любые
пользовательские параметры через атрибут data-scroll-repeat
и дополнительные data-атрибуты:
<div data-scroll data-scroll-call="animateElement" data-scroll-repeat="true" data-color="red"></div>
scroll.on('call', (func, way, obj) => {
if (func === 'animateElement') {
const color = obj.el.dataset.color;
obj.el.style.backgroundColor = color;
}
});
Здесь:
func — имя вызываемой функции
(animateElement);way — направление события
(enter/leave);obj — объект с ссылкой на элемент и его метаданные
(el, id, repeat).Передача данных через dataset позволяет гибко управлять
поведением каждого элемента без жесткой привязки к коду.
Если требуется передать данные, которые не находятся в DOM, можно использовать замыкания:
function createHandler(customData) {
return function(args) {
console.log('Скролл позиции:', args.scroll.y);
console.log('Мои данные:', customData);
};
}
scroll.on('scroll', createHandler({ speed: 2, threshold: 100 }));
Замыкание сохраняет доступ к объекту customData и
позволяет изменять поведение обработчика без модификации глобальных
переменных. Этот подход особенно полезен для сложных интерфейсов с
множеством независимых компонентов.
Locomotive Scroll автоматически кэширует позиции элементов при
инициализации. Чтобы обработчик получал актуальные данные, используется
метод update():
scroll.update();
scroll.on('scroll', (args) => {
args.currentElements.forEach(el => {
if (el.el.dataset.dynamicValue) {
el.el.textContent = el.el.dataset.dynamicValue * args.scroll.y / 100;
}
});
});
Метод update() пересчитывает позиции всех элементов и
позволяет обработчикам получать свежие данные, что критично при
динамическом изменении DOM.
Для комплексных обработчиков лучше использовать единый объект параметров. Это повышает читаемость кода и упрощает поддержку:
const handlerParams = {
speedMultiplier: 1.5,
highlightClass: 'is-active',
limitY: 2000
};
scroll.on('scroll', (args) => {
const scrollY = args.scroll.y * handlerParams.speedMultiplier;
if (scrollY > handlerParams.limitY) {
document.body.classList.add(handlerParams.highlightClass);
} else {
document.body.classList.remove(handlerParams.highlightClass);
}
});
Объект handlerParams объединяет все настройки, которые
нужны обработчику, исключая необходимость использования глобальных
переменных и упрощая модульное тестирование.
В Locomotive Scroll обработчики могут подписываться на разные события и использовать общие данные:
const sharedData = { counter: 0 };
scroll.on('enter', (el) => {
sharedData.counter++;
console.log('Элемент вошёл в видимую область', el.el, sharedData.counter);
});
scroll.on('leave', (el) => {
sharedData.counter--;
console.log('Элемент покинул область', el.el, sharedData.counter);
});
Это позволяет синхронизировать логику между различными элементами и событиями, отслеживая состояние всей страницы через единый объект данных.
Хотите, я подготовлю ещё раздел с примерами анимирования элементов с передачей сложных структур данных в обработчики? Это будет следующая логическая ступень статьи.