Валидация при скролле

Валидация при скролле — это подход, при котором проверка состояния интерфейса или данных выполняется в зависимости от положения страницы. В библиотеке ScrollMagic этот механизм строится на основе сцен (Scene) и контроллера (Controller), реагирующих на изменение позиции прокрутки.

Ключевая идея — связать момент появления или выхода элемента из области видимости с запуском логики проверки.


Архитектура ScrollMagic для валидации

ScrollMagic работает через две основные сущности:

  • Controller — управляет всеми сценами
  • Scene — описывает конкретное событие, привязанное к скроллу

Пример базовой структуры:

var controller = new ScrollMagic.Controller();

var scene = new ScrollMagic.Scene({
    triggerElement: "#form-section",
    triggerHook: 0.8,
    reverse: false
})
.addTo(controller);

Параметры:

  • triggerElement — элемент, при достижении которого срабатывает сцена
  • triggerHook — точка экрана (0–1), где происходит активация
  • reverse — повторное срабатывание при прокрутке вверх

Триггерная валидация формы

Один из распространённых сценариев — проверка формы при достижении определённого блока.

var scene = new ScrollMagic.Scene({
    triggerElement: "#form",
    triggerHook: 0.5
})
.on("enter", function () {
    validateForm();
})
.addTo(controller);

Функция валидации:

function validateForm() {
    const inputs = document.querySelectorAll("#form input[required]");
    
    inputs.forEach(input => {
        if (!input.value.trim()) {
            input.classList.add("error");
        } else {
            input.classList.remove("error");
        }
    });
}

Валидация видимости элементов

ScrollMagic позволяет определять, находится ли элемент в зоне видимости, и на основе этого выполнять проверки.

new ScrollMagic.Scene({
    triggerElement: "#section",
    duration: 300
})
.on("progress", function (event) {
    if (event.progress > 0.5) {
        checkVisibility();
    }
})
.addTo(controller);

event.progress — значение от 0 до 1, отражающее процент прохождения сцены.


Пошаговая валидация (Scroll-driven validation)

Подходит для длинных форм или лендингов с несколькими этапами.

document.querySelectorAll(".step").forEach(step => {
    new ScrollMagic.Scene({
        triggerElement: step,
        triggerHook: 0.7
    })
    .on("enter", function () {
        validateStep(step);
    })
    .addTo(controller);
});
function validateStep(step) {
    const inputs = step.querySelectorAll("input");

    inputs.forEach(input => {
        if (!input.checkValidity()) {
            input.classList.add("invalid");
        }
    });
}

Динамическая валидация при прокрутке

Валидация может происходить непрерывно, а не только при входе в сцену.

new ScrollMagic.Scene({
    triggerElement: "#interactive-block",
    duration: 500
})
.on("progress", function (event) {
    updateValidation(event.progress);
})
.addTo(controller);
function updateValidation(progress) {
    if (progress < 0.3) {
        showHint("Начало заполнения");
    } else if (progress < 0.7) {
        showHint("Почти готово");
    } else {
        showHint("Проверка завершена");
    }
}

Валидация с использованием классов

ScrollMagic позволяет автоматически добавлять/удалять классы, что удобно для CSS-валидации.

new ScrollMagic.Scene({
    triggerElement: "#input-block",
    triggerHook: 0.6
})
.setClassToggle("#input-block", "active-validation")
.addTo(controller);

CSS:

.active-validation input:invalid {
    border-color: red;
}

.active-validation input:valid {
    border-color: green;
}

Обработка событий сцены

Сцены поддерживают несколько событий:

  • enter — вход в область
  • leave — выход
  • start / end — начало/конец сцены
  • progress — изменение прогресса

Пример комплексной валидации:

new ScrollMagic.Scene({
    triggerElement: "#form-section",
    duration: 400
})
.on("enter", () => console.log("Начало проверки"))
.on("progress", e => console.log("Прогресс:", e.progress))
.on("leave", () => finalizeValidation())
.addTo(controller);

Валидация с блокировкой прокрутки

Возможна реализация сценария, при котором пользователь не может продолжить скролл без прохождения проверки.

function blockScroll() {
    document.body.style.overflow = "hidden";
}

function unblockScroll() {
    document.body.style.overflow = "auto";
}
new ScrollMagic.Scene({
    triggerElement: "#critical-section",
    triggerHook: 0.5
})
.on("enter", function () {
    if (!isValid()) {
        blockScroll();
    }
})
.addTo(controller);

Асинхронная валидация

Проверка может включать серверные запросы.

async function validateEmail(email) {
    const response = await fetch(`/validate?email=${email}`);
    const data = await response.json();
    return data.valid;
}

Использование со ScrollMagic:

new ScrollMagic.Scene({
    triggerElement: "#email-input",
    triggerHook: 0.7
})
.on("enter", async function () {
    const email = document.querySelector("#email").value;
    const isValidEmail = await validateEmail(email);

    if (!isValidEmail) {
        showError("Некорректный email");
    }
})
.addTo(controller);

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

При активной валидации важно учитывать:

  • Минимизация DOM-операций
  • Дебаунс/троттлинг для progress
  • Ограничение количества сцен

Пример троттлинга:

function throttle(fn, delay) {
    let last = 0;
    return function () {
        const now = Date.now();
        if (now - last >= delay) {
            fn.apply(this, arguments);
            last = now;
        }
    };
}
.on("progress", throttle(function (event) {
    updateValidation(event.progress);
}, 100));

Связка с анимациями

ScrollMagic часто используется вместе с GSAP, что позволяет визуализировать ошибки или успешную валидацию.

new ScrollMagic.Scene({
    triggerElement: "#form",
    triggerHook: 0.5
})
.on("enter", function () {
    if (!isValid()) {
        gsap.to("#form", { x: -10, repeat: 5, yoyo: true });
    }
})
.addTo(controller);

Типичные ошибки

1. Слишком много сцен Создаёт нагрузку и снижает производительность.

2. Отсутствие reverse: false Валидация может срабатывать повторно при прокрутке вверх.

3. Работа с DOM внутри progress без оптимизации Вызывает лаги при скролле.

4. Несинхронизированная логика Валидация и визуальные эффекты могут расходиться.


Расширенные сценарии

  • Валидация лендингов с историей (storytelling)
  • Контроль прохождения обучающих экранов
  • Проверка заполнения данных перед переходом к следующему блоку
  • Интерактивные анкеты с прокруткой

Комбинирование с IntersectionObserver

Для упрощённых случаев ScrollMagic можно комбинировать или заменять:

const observer = new IntersectionObserver(entries => {
    entries.forEach(entry => {
        if (entry.isIntersecting) {
            validateSection(entry.target);
        }
    });
});

Но ScrollMagic остаётся предпочтительным при сложной логике и анимациях.


Вывод структуры реализации

  1. Создание контроллера
  2. Определение сцен для ключевых блоков
  3. Назначение обработчиков событий
  4. Реализация функций валидации
  5. Оптимизация производительности
  6. Добавление визуальной обратной связи

Такой подход позволяет синхронизировать поведение интерфейса с прокруткой и создавать сложные интерактивные сценарии проверки данных.