Intro.js — это библиотека для создания пошаговых интерактивных руководств на веб-страницах. Один из ключевых аспектов её использования — возможность сохранять прогресс пользователя, чтобы при повторном посещении сайта руководство не начиналось заново. Для этого используется браузерное хранилище localStorage, предоставляющее постоянное хранение данных на стороне клиента.
Для начала подключается сама библиотека Intro.js:
<link rel="stylesheet" href="https://unpkg.com/intro.js/minified/introjs.min.css">
<script src="https://unpkg.com/intro.js/minified/intro.min.js"></script>
Инициализация стандартного руководства:
const intro = introJs();
intro.setOptions({
steps: [
{ element: '#step1', intro: 'Это первый шаг.' },
{ element: '#step2', intro: 'Это второй шаг.' },
{ element: '#step3', intro: 'Это третий шаг.' }
],
showProgress: true,
exitOnOverlayClick: false
});
LocalStorage позволяет хранить данные в виде пар ключ-значение, где значение обязательно должно быть строкой. Для сохранения шага руководства используется следующий подход:
intro.onchange(function(targetElement) {
const currentStep = intro._currentStep;
localStorage.setItem('introjsCurrentStep', currentStep);
});
Для того чтобы продолжить руководство с того шага, на котором пользователь остановился:
const savedStep = localStorage.getItem('introjsCurrentStep');
if (savedStep !== null) {
intro.start().goToStep(Number(savedStep + 1)).start();
} else {
intro.start();
}
Number,
так как localStorage хранит только строки.В некоторых случаях требуется, чтобы руководство начиналось заново после завершения или по определённому условию:
intro.oncomplete(function() {
localStorage.removeItem('introjsCurrentStep');
});
intro.onexit(function() {
localStorage.removeItem('introjsCurrentStep');
});
Для более сложных сценариев можно сохранять не только текущий шаг, но и другие параметры, например, отмеченные опции:
intro.onchange(function() {
const progress = {
currentStep: intro._currentStep,
completedSteps: intro._introItems
.filter(item => item._introCompleted)
.map(item => item.element.id)
};
localStorage.setItem('introProgress', JSON.stringify(progress));
});
const savedProgress = JSON.parse(localStorage.getItem('introProgress') || '{}');
if (savedProgress.currentStep !== undefined) {
intro.start().goToStep(savedProgress.currentStep + 1).start();
}
onchange) для минимизации записи в localStorage.document.addEventListener('DOMContentLoaded', () => {
const intro = introJs();
intro.setOptions({
steps: [
{ element: '#step1', intro: 'Первый шаг.' },
{ element: '#step2', intro: 'Второй шаг.' },
{ element: '#step3', intro: 'Третий шаг.' }
],
showProgress: true,
exitOnOverlayClick: false
});
const savedStep = localStorage.getItem('introjsCurrentStep');
if (savedStep !== null) {
intro.goToStep(Number(savedStep) + 1);
}
intro.onchange(function() {
localStorage.setItem('introjsCurrentStep', intro._currentStep);
});
intro.oncomplete(function() {
localStorage.removeItem('introjsCurrentStep');
});
intro.onexit(function() {
localStorage.removeItem('introjsCurrentStep');
});
intro.start();
});
Такой подход обеспечивает плавное сохранение прогресса, возможность продолжения с последнего шага и корректное завершение руководства без утечек данных.