Вложенные скроллы

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

Настройка родительского и дочернего контейнера

Для корректной работы вложенных скроллов необходимо четко определить роли контейнеров. Родительский контейнер отвечает за общий вертикальный скролл страницы, а дочерний — за локальную прокрутку. Основные шаги:

  1. Указать уникальные data-scroll-container для родительского блока.
  2. Дочерний блок с прокруткой также может быть инициализирован как отдельный экземпляр Locomotive Scroll, либо настроен с помощью 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-repeat

Вложенные скроллы влияют на триггеры анимаций. Для элементов внутри дочернего скролла важно использовать:

  • 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();

Это гарантирует правильное вычисление позиций и триггеров для вложенных элементов.

Рекомендации по производительности

  1. Не включать smooth для всех вложенных скроллов, особенно с большим количеством элементов.
  2. Минимизировать количество внутренних экземпляров — по возможности использовать data-scroll внутри родительского.
  3. Отслеживать события скролла выборочно для предотвращения лишних рендеров.

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