Shepherd.js — это библиотека для создания интерактивных пользовательских туров на веб-страницах. Одной из важных задач при работе с турами является сохранение прогресса пользователя и возможность продолжить тур после перезагрузки страницы или закрытия браузера. Этот механизм называется персистентностью состояния.
Shepherd.js не предоставляет встроенного механизма для хранения состояния между сессиями, поэтому разработчики используют внешние хранилища:
Пример использования LocalStorage для сохранения шага текущего тура:
const tour = new Shepherd.Tour({
defaultStepOptions: {
scrollTo: true,
cancelIcon: { enabled: true }
}
});
tour.addStep({
id: 'step-1',
text: 'Это первый шаг',
attachTo: { element: '#step1', on: 'bottom' },
buttons: [
{
text: 'Далее',
action: () => {
localStorage.setItem('tourStep', 'step-2');
tour.next();
}
}
]
});
tour.addStep({
id: 'step-2',
text: 'Второй шаг тура',
attachTo: { element: '#step2', on: 'top' },
buttons: [
{
text: 'Назад',
action: () => {
localStorage.setItem('tourStep', 'step-1');
tour.back();
}
}
]
});
// Восстановление состояния при загрузке страницы
const savedStep = localStorage.getItem('tourStep');
if (savedStep) {
tour.start();
tour.show(savedStep);
} else {
tour.start();
}
Для корректной персистентности необходимо учитывать несколько моментов:
id, чтобы можно было точно определить, на
каком этапе остановился пользователь.tour.on('show', (event) => {
localStorage.setItem('tourStep', event.step.id);
});
tour.on('complete', () => {
localStorage.removeItem('tourStep');
});
Для более сложных сценариев, например, когда тур состоит из динамических шагов или пользователь может возвращаться к различным частям интерфейса, стоит использовать объект состояния, хранящий не только текущий шаг, но и дополнительные параметры:
const tourState = {
currentStep: 'step-1',
completedSteps: [],
dismissed: false
};
tour.on('show', (event) => {
tourState.currentStep = event.step.id;
if (!tourState.completedSteps.includes(event.step.id)) {
tourState.completedSteps.push(event.step.id);
}
localStorage.setItem('tourState', JSON.stringify(tourState));
});
tour.on('complete', () => {
tourState.dismissed = true;
localStorage.setItem('tourState', JSON.stringify(tourState));
});
Такой подход позволяет:
Если приложение требует синхронизации прогресса между устройствами, состояние тура можно отправлять на сервер через API:
fetch('/api/tour-state', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(tourState)
});
При загрузке страницы сервер может вернуть состояние пользователя, чтобы возобновить тур:
fetch('/api/tour-state')
.then(res => res.json())
.then(data => {
if (data && !data.dismissed) {
tour.start();
tour.show(data.currentStep);
}
});
show, чтобы избежать ошибок при удалении элементов
DOM.tour.on('cancel', ...) для очистки
состояния при явном закрытии тура пользователем.Персистентность состояния в Shepherd.js позволяет создавать гибкие, надёжные туры, которые учитывают действия пользователя, обеспечивают удобство возвращения к интерфейсу и интеграцию с клиентским и серверным хранилищем.