Shepherd.js предоставляет гибкий механизм создания интерактивных руководств (tours) для веб-приложений. Одной из важных возможностей является асинхронная валидация шагов, которая позволяет управлять переходом между шагами на основе динамических условий.
Каждый шаг Shepherd.js может содержать обработчики событий, включая
beforeShowPromise и beforeNext. Эти
обработчики позволяют выполнять асинхронные операции, прежде чем шаг
будет показан или завершён:
const tour = new Shepherd.Tour({
defaultStepOptions: {
scrollTo: true
}
});
tour.addStep({
id: 'step-1',
text: 'Введите своё имя',
attachTo: { element: '#name-input', on: 'bottom' },
buttons: [
{
text: 'Далее',
action: tour.next
}
],
beforeShowPromise: () => {
return new Promise((resolve, reject) => {
const input = document.querySelector('#name-input');
if (input.value.trim() !== '') {
resolve();
} else {
alert('Поле не может быть пустым');
reject();
}
});
}
});
В примере выше beforeShowPromise
проверяет содержимое поля ввода и блокирует показ шага до выполнения
условия. Промис может быть отклонён, что предотвратит отображение шага и
позволит пользователю исправить ошибку.
beforeNext для динамической проверкиbeforeNext вызывается перед переходом к следующему шагу.
Этот метод идеально подходит для валидации данных, введённых
пользователем, перед продолжением тура:
tour.addStep({
id: 'step-2',
text: 'Введите корректный email',
attachTo: { element: '#email-input', on: 'right' },
buttons: [
{
text: 'Далее',
action: tour.next
}
],
beforeNext: () => {
return new Promise((resolve, reject) => {
const email = document.querySelector('#email-input').value;
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (emailRegex.test(email)) {
resolve();
} else {
alert('Введите корректный email');
reject();
}
});
}
});
Ключевой момент: использование промисов позволяет не блокировать основной поток JavaScript и корректно обрабатывать асинхронные операции, такие как сетевые запросы или таймеры.
Иногда необходимо проверять данные не локально, а отправляя их на
сервер для проверки. В таких случаях beforeNext можно
комбинировать с fetch или любым другим API-запросом:
tour.addStep({
id: 'step-3',
text: 'Проверка доступности имени пользователя',
attachTo: { element: '#username-input', on: 'top' },
buttons: [
{
text: 'Далее',
action: tour.next
}
],
beforeNext: () => {
const username = document.querySelector('#username-input').value;
return fetch(`/api/check-username?username=${username}`)
.then(response => response.json())
.then(data => {
if (data.available) {
return Promise.resolve();
} else {
alert('Имя пользователя занято');
return Promise.reject();
}
});
}
});
Такой подход обеспечивает динамическую валидацию данных в реальном времени и позволяет интегрировать Shepherd.js с серверной логикой приложения.
Для улучшения взаимодействия важно корректно обрабатывать отклонённые промисы:
beforeNext: () => {
const loader = document.querySelector('#loader');
loader.style.display = 'block';
return fetch('/api/validate')
.then(res => res.json())
.finally(() => {
loader.style.display = 'none';
})
.then(data => {
if (data.valid) {
return Promise.resolve();
} else {
return Promise.reject();
}
});
}
beforeShowPromise для
проверки условий перед показом шага.beforeNext для асинхронной
валидации перед переходом к следующему шагу.Асинхронная валидация в Shepherd.js превращает стандартные туры в интерактивные, динамичные и безопасные руководства, способные реагировать на действия пользователя и данные приложения в реальном времени.