Валидация при скролле — это подход, при котором проверка состояния
интерфейса или данных выполняется в зависимости от положения страницы. В
библиотеке ScrollMagic этот механизм строится на основе сцен
(Scene) и контроллера (Controller),
реагирующих на изменение позиции прокрутки.
Ключевая идея — связать момент появления или выхода элемента из области видимости с запуском логики проверки.
ScrollMagic работает через две основные сущности:
Пример базовой структуры:
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, отражающее процент прохождения сцены.
Подходит для длинных форм или лендингов с несколькими этапами.
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);
При активной валидации важно учитывать:
Пример троттлинга:
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. Несинхронизированная логика Валидация и визуальные эффекты могут расходиться.
Для упрощённых случаев ScrollMagic можно комбинировать или заменять:
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
validateSection(entry.target);
}
});
});
Но ScrollMagic остаётся предпочтительным при сложной логике и анимациях.
Такой подход позволяет синхронизировать поведение интерфейса с прокруткой и создавать сложные интерактивные сценарии проверки данных.