Media queries и реинициализация

Locomotive Scroll — мощная библиотека для плавного скролла и управления анимациями при прокрутке. Часто возникает необходимость адаптировать поведение скролла под разные размеры экранов. Для этого используются media queries и механизмы реинициализации.


Настройка Locomotive Scroll с условием медиа-запроса

Для начала создаём экземпляр скролла с базовыми опциями:

import LocomotiveScroll from 'locomotive-scroll';

let scroll = new LocomotiveScroll({
  el: document.querySelector('[data-scroll-container]'),
  smooth: true,
  lerp: 0.1,
});

Чтобы включить или отключить плавный скролл в зависимости от ширины экрана, используют window.matchMedia:

const mq = window.matchMedia('(min-width: 1024px)');
let scrollInstance;

function initScroll() {
  if (mq.matches) {
    scrollInstance = new LocomotiveScroll({
      el: document.querySelector('[data-scroll-container]'),
      smooth: true,
      lerp: 0.1,
    });
  } else {
    if (scrollInstance) {
      scrollInstance.destroy();
      scrollInstance = null;
    }
  }
}

mq.addEventListener('change', initScroll);
window.addEventListener('load', initScroll);

Ключевые моменты:

  • mq.matches возвращает true, если условие media query выполняется.
  • При переключении между состояниями важно уничтожать существующий экземпляр скролла методом .destroy(), чтобы избежать утечек памяти или конфликтов с анимациями.
  • Использование addEventListener('change', ...) позволяет автоматически реагировать на изменение ширины окна.

Реинициализация после изменения DOM

Если контент страницы динамически изменяется (например, добавляются новые секции, изображения или асинхронные блоки), необходимо обновить скролл:

scrollInstance.update();

Сценарии применения:

  • Загрузка изображений или видео.
  • Добавление новых элементов через JavaScript.
  • Появление/скрытие модальных окон, влияющих на высоту контейнера.

Важно: update() пересчитывает позиции всех элементов с атрибутом data-scroll, но не создаёт новый экземпляр. Для изменения настроек потребуется сначала вызвать .destroy() и затем создать новый объект.


Управление скроллом в адаптивном дизайне

Часто встречается ситуация, когда на мобильных устройствах нужно отключить smooth scroll. В таком случае media queries и реинициализация работают вместе:

function responsiveScroll() {
  const width = window.innerWidth;

  if (width >= 1024) {
    if (!scrollInstance) {
      scrollInstance = new LocomotiveScroll({
        el: document.querySelector('[data-scroll-container]'),
        smooth: true,
        lerp: 0.1,
      });
    }
  } else {
    if (scrollInstance) {
      scrollInstance.destroy();
      scrollInstance = null;
    }
  }
}

window.addEventListener('resize', responsiveScroll);
window.addEventListener('load', responsiveScroll);

Особенности:

  • Проверка состояния перед созданием нового экземпляра предотвращает многократную инициализацию.
  • destroy() полностью очищает события, inline-стили и слушатели библиотеки.
  • Вызов функции на событии resize позволяет плавно переключаться между режимами при повороте экрана или изменении размера окна.

Использование reset() для переинициализации отдельных эффектов

Locomotive Scroll предоставляет метод reset(), который полезен для повторного расчёта позиций и триггеров без уничтожения всего скролла:

scrollInstance.reset();

Применяется, когда:

  • Меняется размер отдельного блока.
  • Появляются новые элементы с data-scroll или data-scroll-speed.
  • Не требуется полностью уничтожать и создавать скролл заново.

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


Сложные кейсы: сочетание media queries и динамического контента

Если проект содержит сложные анимации, ленивую загрузку изображений и адаптивный дизайн, рекомендуется объединять подходы:

  1. Использовать media queries для условного включения smooth scroll.
  2. После загрузки нового контента или изменения DOM вызывать update() или reset().
  3. При смене условий media query уничтожать и пересоздавать экземпляр.
function dynamicResponsiveScroll() {
  const mq = window.matchMedia('(min-width:1024px)');
  if (mq.matches) {
    if (!scrollInstance) {
      scrollInstance = new LocomotiveScroll({
        el: document.querySelector('[data-scroll-container]'),
        smooth: true,
        lerp: 0.1,
      });
    } else {
      scrollInstance.update();
    }
  } else {
    if (scrollInstance) {
      scrollInstance.destroy();
      scrollInstance = null;
    }
  }
}

window.addEventListener('resize', dynamicResponsiveScroll);
window.addEventListener('load', dynamicResponsiveScroll);

Такой подход гарантирует, что:

  • Smooth scroll работает только на нужных устройствах.
  • Добавление нового контента не нарушает логику скролла.
  • Переинициализация выполняется безопасно, без дублирования событий и утечек памяти.

Практические рекомендации

  • Все элементы, которые должны участвовать в эффекте скролла, маркируются атрибутом data-scroll.
  • Для оптимизации производительности при resize лучше использовать debounce или throttle.
  • После destroy() inline-стили и transform свойства, установленные библиотекой, полностью убираются, что предотвращает визуальные артефакты.
  • Media queries в JS позволяют управлять скроллом гибко, но важно тестировать на разных разрешениях и при изменении ориентации экрана.

Media queries и реинициализация являются фундаментальными инструментами для построения адаптивного и динамичного скролла с Locomotive Scroll, обеспечивая стабильное поведение и корректную работу анимаций на любых устройствах.