Locomotive Scroll предоставляет удобный механизм для плавного скролла с эффектом параллакса, однако работа с вложенными скроллами требует особого внимания. Вложенные скроллы возникают, когда внутри основного контейнера скролла находится элемент с собственной прокруткой (например, горизонтальная карусель или отдельный блок с overflow). Без правильной конфигурации это может приводить к конфликтам и неправильному поведению анимаций.
Для корректной работы вложенных скроллов необходимо четко определить роли контейнеров. Родительский контейнер отвечает за общий вертикальный скролл страницы, а дочерний — за локальную прокрутку. Основные шаги:
data-scroll-container для
родительского блока.data-scroll для отслеживания позиции.Пример HTML-структуры:
<div data-scroll-container>
<section data-scroll-section>
<div class="nested-scroll" data-scroll data-scroll-repeat>
<div class="nested-content">
<!-- Длинный контент для внутреннего скролла -->
</div>
</div>
</section>
</div>
При инициализации родительского скролла используется стандартный синтаксис:
import LocomotiveScroll from 'locomotive-scroll';
const scroll = new LocomotiveScroll({
el: document.querySelector('[data-scroll-container]'),
smooth: true,
getDirection: true
});
Для внутреннего скролла рекомендуется либо отключить плавность, либо использовать отдельный экземпляр с вертикальной или горизонтальной прокруткой:
const nestedScroll = new LocomotiveScroll({
el: document.querySelector('.nested-scroll'),
smooth: false,
direction: 'vertical'
});
Если дочерний скролл предназначен только для отслеживания позиции
элементов, можно обойтись без создания отдельного экземпляра, используя
атрибуты data-scroll и data-scroll-repeat.
Проблема вложенных скроллов заключается в том, что событие
scroll родительского контейнера может не
распространяться на внутренние блоки, что мешает запуску
анимаций. Locomotive Scroll предоставляет возможность подписываться на
события для каждого экземпляра:
scroll.on('scroll', (args) => {
console.log('Родительский скролл', args.scroll.y);
});
nestedScroll.on('scroll', (args) => {
console.log('Внутренний скролл', args.scroll.y);
});
Для сложных интерфейсов иногда требуется обновление позиции
родителя при скролле дочернего элемента, что реализуется
методом scroll.update().
Вложенные скроллы влияют на триггеры анимаций. Для элементов внутри дочернего скролла важно использовать:
data-scroll для отслеживания позиции относительно
текущего контейнера.data-scroll-repeat для повторного срабатывания анимаций
при повторном входе в область видимости.Пример анимации:
<div class="nested-item" data-scroll data-scroll-repeat data-scroll-class="is-visible">
Контент с анимацией при скролле
</div>
Для горизонтальных каруселей применяется настройка
direction: 'horizontal' и обязательное указание
el на элемент с overflow. При этом необходимо
учитывать:
data-scroll-direction="horizontal" для корректного
отслеживания прогресса.Пример инициализации горизонтального блока:
const horizontalScroll = new LocomotiveScroll({
el: document.querySelector('.horizontal-scroll'),
smooth: true,
direction: 'horizontal'
});
При изменении размера окна или динамическом добавлении контента
необходимо вызывать метод update() для
всех экземпляров скролла:
scroll.update();
nestedScroll.update();
horizontalScroll.update();
Это гарантирует правильное вычисление позиций и триггеров для вложенных элементов.
data-scroll внутри
родительского.Вложенные скроллы позволяют создавать сложные интерактивные интерфейсы с каруселями, параллаксом и анимациями, но требуют внимательной настройки контейнеров, событий и атрибутов элементов для стабильной и плавной работы.