Подгрузка контента и ajax

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

import LocomotiveScroll from 'locomotive-scroll';

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

При первом запуске скролла, Locomotive Scroll обрабатывает все элементы, которые уже находятся в DOM. Если контент подгружается динамически, необходимо перезапустить обработку новых элементов, иначе эффекты и триггеры работать не будут.


Обновление скролла после AJAX-загрузки

Когда контент подгружен через AJAX, вызов метода update() пересчитывает позиции всех элементов и обновляет внутренние состояния:

fetch('/load-more')
  .then(response => response.text())
  .then(html => {
    const container = document.querySelector('.content');
    container.insertAdjacentHTML('beforeend', html);
    
    // Обновление Locomotive Scroll
    scroll.update();
  });

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

  • insertAdjacentHTML или appendChild добавляют элементы в DOM.
  • scroll.update() пересчитывает позиции и размеры всех элементов.
  • Если новые элементы содержат атрибуты data-scroll, они будут автоматически зарегистрированы для триггеров анимации и параллакса.

Использование scroll.update() с отложенной анимацией

Иногда AJAX-контент подгружается с задержкой или анимацией. В таких случаях стоит обновлять скролл после полной вставки контента и завершения рендеринга:

fetch('/load-section')
  .then(res => res.text())
  .then(html => {
    const section = document.querySelector('.sections');
    section.insertAdjacentHTML('beforeend', html);

    // Ждем завершения рендера
    requestAnimationFrame(() => {
      scroll.update();
    });
  });

requestAnimationFrame гарантирует, что обновление произойдет после того, как браузер рассчитает стили и отрисует новые элементы, что предотвращает «прыжки» скролла.


Обработка событий на динамически подгружаемых элементах

Locomotive Scroll позволяет навешивать события на элементы через data-scroll и data-scroll-call. Для динамического контента важно повторно подключать обработчики:

<div data-scroll data-scroll-call="fadeIn" class="fade-block">
  Новый блок
</div>
scroll.on('call', (func, direction, obj) => {
  if(func === 'fadeIn') {
    obj.el.classList.add('visible');
  }
});

При добавлении новых блоков через AJAX, scroll автоматически регистрирует их, если после вставки вызвать scroll.update(). Без этого новые элементы не будут участвовать в событиях.


Подгрузка больших объемов контента

Для бесконечной прокрутки (infinite scroll) с Locomotive Scroll важно:

  1. Подгружать контент блоками.
  2. После каждой загрузки вызывать scroll.update().
  3. Оптимизировать DOM, удаляя устаревшие элементы при необходимости.
  4. Следить за производительностью, так как большое количество элементов с триггерами может замедлить рендер.

Пример бесконечной прокрутки:

window.addEventListener('scroll', () => {
  if (window.scrollY + window.innerHeight > document.body.offsetHeight - 500) {
    loadMoreContent();
  }
});

function loadMoreContent() {
  fetch('/next-page')
    .then(res => res.text())
    .then(html => {
      document.querySelector('.content').insertAdjacentHTML('beforeend', html);
      scroll.update();
    });
}

Интеграция с фреймворками и SPA

В SPA (React, Vue, Svelte) Locomotive Scroll работает аналогично, но важно:

  • Инициализировать скролл после монтирования компонента.
  • Вызывать scroll.update() после добавления новых маршрутов или контента.
  • Очищать и уничтожать скролл при размонтировании компонента:
useEffect(() => {
  const scroll = new LocomotiveScroll({ el: containerRef.current, smooth: true });
  
  return () => {
    scroll.destroy();
  };
}, []);

Оптимизация работы с AJAX-контентом

  • Делать минимальные вставки в DOM — добавлять сразу блоки, а не отдельные элементы.
  • Отложенные анимации — использовать requestAnimationFrame или setTimeout для плавного обновления.
  • Виртуализация — при огромных списках стоит отображать только видимую часть и динамически подгружать остальное.
  • События scroll — подписки лучше использовать через scroll.on('scroll', ...), а не нативный window.onscroll, чтобы синхронизировать с Locomotive Scroll.

Работа с асинхронными изображениями и медиа

Если AJAX-контент содержит изображения или видео, важно дождаться их загрузки, иначе позиции элементов могут считаться некорректно:

const imgs = document.querySelectorAll('img');
let loaded = 0;

imgs.forEach(img => {
  img.onl oad = () => {
    loaded++;
    if (loaded === imgs.length) {
      scroll.update();
    }
  };
});

Это гарантирует, что скролл учитывает размеры всех медиа, предотвращая «скачки» при появлении контента.


Резюме ключевых методов

  • scroll.update() — пересчет всех позиций и регистрация новых элементов.
  • scroll.destroy() — удаление скролла и всех обработчиков.
  • scroll.on('call', callback) — обработка триггеров элементов с data-scroll-call.
  • requestAnimationFrame() — синхронизация обновлений после рендера динамического контента.
  • Асинхронная загрузка медиа — обязательна для корректного расчета высоты контейнера.

Правильное сочетание этих методов позволяет безупречно интегрировать Locomotive Scroll с любым AJAX-контентом, обеспечивая плавность скролла и точное срабатывание эффектов.