AJAX-загрузка при скролле

ScrollMagic — это мощная библиотека для создания скролл-анимаций и управления событиями в зависимости от положения страницы. Одним из ключевых сценариев использования является динамическая подгрузка контента через AJAX по мере прокрутки страницы, что позволяет создавать ленивую загрузку или «бесконечный скролл».


Настройка сцены ScrollMagic для AJAX

Для реализации AJAX-загрузки необходимо создать сцену ScrollMagic, которая будет отслеживать положение скролла относительно элемента или страницы. Основные шаги:

  1. Инициализация контроллера:
var controller = new ScrollMagic.Controller();
  1. Создание сцены для триггера подгрузки:
var scene = new ScrollMagic.Scene({
    triggerElement: "#loadMoreTrigger", // элемент, у которого наступает событие
    triggerHook: 1, // 1 — нижняя граница окна
    reverse: false  // событие срабатывает один раз
})
.addTo(controller);

triggerHook: 1 указывает, что событие сработает, когда элемент дойдет до нижней границы окна просмотра. reverse: false гарантирует, что подгрузка будет однократной, предотвращая повторные запросы при прокрутке назад.


Обработка события триггера

ScrollMagic позволяет навесить обработчик события enter, который срабатывает при активации сцены:

scene.on("enter", function () {
    loadMoreContent();
});

Здесь loadMoreContent — функция, выполняющая AJAX-запрос для подгрузки новых элементов.


AJAX-запрос с использованием Fetch API

Для динамической подгрузки контента можно использовать современный Fetch API:

function loadMoreContent() {
    fetch("/get-more-items?page=2")
        .then(response => {
            if (!response.ok) {
                throw new Error("Ошибка сети");
            }
            return response.text();
        })
        .then(html => {
            const container = document.querySelector("#contentContainer");
            const tempDiv = document.createElement("div");
            tempDiv.innerHTML = html;
            while (tempDiv.firstChild) {
                container.appendChild(tempDiv.firstChild);
            }
        })
        .catch(error => console.error("Ошибка подгрузки:", error));
}
  • #contentContainer — контейнер, куда будут добавляться новые элементы.
  • fetch получает HTML с сервера.
  • Использование временного div позволяет корректно вставлять полученный контент.

Поддержка нескольких страниц и повторных триггеров

Для реализации «бесконечного скролла» необходимо динамически обновлять сцены или изменять триггер после подгрузки:

let currentPage = 1;
let isLoading = false;

function loadMoreContent() {
    if (isLoading) return;
    isLoading = true;
    currentPage++;

    fetch(`/get-more-items?page=${currentPage}`)
        .then(response => response.text())
        .then(html => {
            const container = document.querySelector("#contentContainer");
            const tempDiv = document.createElement("div");
            tempDiv.innerHTML = html;
            while (tempDiv.firstChild) {
                container.appendChild(tempDiv.firstChild);
            }
            isLoading = false;

            // Перемещаем триггер ниже нового контента
            const trigger = document.querySelector("#loadMoreTrigger");
            trigger.scrollIntoView(false); // или обновить положение сцены
        })
        .catch(error => {
            console.error("Ошибка подгрузки:", error);
            isLoading = false;
        });
}

Здесь isLoading предотвращает дублирование запросов, если пользователь прокручивает страницу слишком быстро.


Интеграция с анимацией ScrollMagic

Подгруженный контент можно сразу анимировать с помощью ScrollMagic и TweenMax/GSAP:

function animateNewItems(items) {
    items.forEach(item => {
        gsap.from(item, {opacity: 0, y: 50, duration: 0.6});
    });
}

После вставки нового контента в #contentContainer можно вызвать:

animateNewItems(document.querySelectorAll("#contentContainer .new-item"));

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


Оптимизация подгрузки

  • Дебаунс события: если скролл срабатывает слишком часто, полезно добавить задержку.
  • Предзагрузка: можно подгружать следующий блок до достижения триггера для более плавного опыта.
  • Lazy Loading изображений: изображения загружать только при появлении в зоне видимости через IntersectionObserver.

Использование setPin для фиксации элементов при загрузке

Иногда нужно закрепить триггерный элемент, пока происходит подгрузка:

var pinScene = new ScrollMagic.Scene({
    triggerElement: "#loadMoreTrigger",
    duration: 200
})
.setPin("#loadMoreTrigger")
.addTo(controller);

Такой подход обеспечивает визуальную индикацию загрузки и предотвращает потерю триггера за пределами окна просмотра.


Заключение по архитектуре

  • Создаётся контроллер ScrollMagic для управления сценами.
  • Сцена триггера отслеживает скролл и вызывает AJAX-запрос.
  • Полученный HTML вставляется в DOM динамически.
  • Дополнительно элементы можно анимировать с GSAP.
  • Оптимизация предотвращает лишние запросы и делает скролл плавным.

Использование ScrollMagic совместно с AJAX позволяет создавать масштабируемые интерфейсы с «ленивой загрузкой» и интегрировать их с любыми анимациями на странице.