Smooth Scroll в JavaScript позволяет создавать плавное прокручивание страницы к определённым элементам, что особенно полезно при работе с формами. Когда форма содержит поля с валидацией, особенно асинхронной или многоступенчатой, важно обеспечить корректное взаимодействие между логикой валидации и механизмом прокрутки, чтобы пользователь сразу видел ошибки и не терял контекст.
Для начала необходимо определить элементы, к которым будет выполняться прокрутка при обнаружении ошибки. Обычно это элементы формы, помеченные классами ошибок, например:
const scroll = new SmoothScroll();
function scrollToError(errorElement) {
scroll.animateScroll(errorElement, null, {
speed: 600,
offset: 50,
easing: 'easeInOutCubic'
});
}
Ключевые параметры:
speed – скорость прокрутки в миллисекундах.offset – смещение от верхнего края окна, полезно при
фиксированных шапках.easing – функция сглаживания движения, улучшает
визуальное восприятие.Если библиотека валидации работает синхронно (например, проверка на пустоту или длину строки), прокрутку можно вызывать сразу после проверки:
const form = document.querySelector('#contactForm');
form.addEventListener('submit', (e) => {
e.preventDefault();
const firstError = form.querySelector('.error');
if(firstError) {
scrollToError(firstError);
} else {
form.submit();
}
});
Особенности:
querySelector('.error') выбирает первый элемент с
ошибкой.e.preventDefault(), чтобы пользователь успел увидеть
ошибку.Для асинхронной валидации (например, проверка уникальности email на сервере) Smooth Scroll необходимо запускать после завершения запроса:
async function validateEmail(input) {
const response = await fetch(`/validate-email?email=${input.value}`);
const result = await response.json();
if(!result.valid) {
input.classList.add('error');
scrollToError(input);
} else {
input.classList.remove('error');
}
}
Особенности:
error должно происходить
после получения результата запроса.При работе с популярными библиотеками, такими как
Formik, Yup или
Parsley.js, важно учитывать их внутренние события.
Например, в Parsley.js можно использовать событие
form:validated:
$('#myForm').parsley().on('form:validated', function() {
const firstError = this.$element.find('.parsley-error').first();
if(firstError.length) {
scrollToError(firstError[0]);
}
});
Ключевые моменты:
form:validated срабатывает после всех
проверок..first(), чтобы
прокручивать к первому полю с ошибкой, а не ко всем сразу.this.$element содержит DOM-элементы формы, что
облегчает поиск ошибок.Если форма содержит динамические поля, добавляемые через JavaScript, необходимо убедиться, что Smooth Scroll вызывается после их вставки в DOM:
function addField() {
const newInput = document.createElement('input');
newInput.setAttribute('type', 'text');
newInput.classList.add('dynamic-field');
form.appendChild(newInput);
}
form.addEventListener('submit', (e) => {
e.preventDefault();
const firstError = form.querySelector('.error');
if(firstError) {
// Прокрутка после вставки динамических полей
setTimeout(() => scrollToError(firstError), 50);
}
});
Особенности:
setTimeout гарантирует, что браузер
успеет отрендерить новый элемент.В формах с вкладками или аккордеонами необходимо сначала открыть соответствующий раздел, а затем выполнять прокрутку:
function scrollToStepError(errorElement) {
const parentStep = errorElement.closest('.step');
if(parentStep && !parentStep.classList.contains('active')) {
parentStep.classList.add('active');
}
scrollToError(errorElement);
}
Особенности:
closest('.step') находит контейнер шага формы.active открывает скрытую вкладку перед
прокруткой.При использовании фиксированных заголовков или динамически изменяющихся панелей стоит вычислять смещение программно:
function getHeaderOffset() {
const header = document.querySelector('header');
return header ? header.offsetHeight + 10 : 0;
}
scroll.animateScroll(firstError, null, {
speed: 600,
offset: getHeaderOffset(),
easing: 'easeInOutCubic'
});
Преимущества:
animateScroll.Эта методология обеспечивает надежное взаимодействие между Smooth Scroll и любыми библиотеками валидации, делая формы удобными для пользователей и предотвращая потерю контекста при ошибках.