Структура кода туров в Shepherd.js строится вокруг трёх ключевых сущностей: тур (Tour), шаг (Step) и конфигурация (Options). Правильная организация этих элементов определяет читаемость, расширяемость и устойчивость кода.
Тур — это основной управляющий объект, который инкапсулирует последовательность шагов и их поведение.
const tour = new Shepherd.Tour({
defaultStepOptions: {
cancelIcon: {
enabled: true
},
classes: 'shepherd-theme-default',
scrollTo: true
},
useModalOverlay: true
});
Шаг представляет собой единичный элемент тура — подсказку, привязанную к элементу интерфейса.
tour.addStep({
id: 'example-step',
text: 'Описание шага',
attachTo: {
element: '.example-selector',
on: 'bottom'
},
buttons: [
{
text: 'Далее',
action: tour.next
}
]
});
Содержимое подсказки:
text: 'Текст шага'
Допускается:
Привязка к элементу:
attachTo: {
element: '.selector',
on: 'top'
}
Позиции:
topbottomleftrightautoЕсли элемент отсутствует — шаг может не отображаться.
Кнопки управления:
buttons: [
{
text: 'Назад',
action: tour.back
},
{
text: 'Далее',
action: tour.next
}
]
Возможные действия:
tour.nexttour.backtour.cancelУникальный идентификатор шага:
id: 'step-1'
Используется для:
CSS-классы:
classes: 'custom-step-class'
Позволяет:
Автоматическая прокрутка:
scrollTo: true
Или с параметрами:
scrollTo: {
beh * avior: 'smooth',
block: 'center'
}
Шаги добавляются последовательно:
tour.addStep({...});
tour.addStep({...});
tour.addStep({...});
Порядок добавления = порядок показа.
Для масштабируемых проектов туры разбиваются на модули.
function createIntroStep(tour) {
return {
id: 'intro',
text: 'Добро пожаловать',
buttons: [
{
text: 'Далее',
action: tour.next
}
]
};
}
Использование:
tour.addStep(createIntroStep(tour));
const steps = [
{
id: 'step1',
text: 'Шаг 1'
},
{
id: 'step2',
text: 'Шаг 2'
}
];
steps.forEach(step => tour.addStep(step));
class TourBuilder {
constructor() {
this.tour = new Shepherd.Tour();
}
addSteps() {
this.tour.addStep({
id: 'step1',
text: 'Шаг 1'
});
}
build() {
this.addSteps();
return this.tour;
}
}
tour.start();
tour.next();
tour.back();
tour.cancel();
tour.complete();
tour.on('start', () => {});
tour.on('complete', () => {});
tour.on('cancel', () => {});
tour.on('show', (event) => {});
Событие show даёт доступ к текущему шагу:
tour.on('show', (event) => {
console.log(event.step.id);
});
Шаги могут отображаться динамически.
tour.addStep({
id: 'conditional-step',
text: 'Появляется при условии',
when: {
show: function () {
return someCondition;
}
}
});
Поддержка ожидания перед показом:
tour.addStep({
id: 'async-step',
beforeShowPromise: function () {
return new Promise(resolve => {
setTimeout(resolve, 1000);
});
}
});
Используется для:
Если элемент появляется динамически:
beforeShowPromise: function () {
return new Promise(resolve => {
const interval = setInterval(() => {
if (document.querySelector('.dynamic')) {
clearInterval(interval);
resolve();
}
}, 100);
});
}
const defaultOptions = {
classes: 'custom-theme',
scrollTo: true
};
const tour = new Shepherd.Tour({
defaultStepOptions: defaultOptions
});
const baseStep = {
buttons: [
{
text: 'Далее',
action: tour.next
}
]
};
tour.addStep({
...baseStep,
id: 'step1',
text: 'Шаг 1'
});
Рекомендуется разделять:
/tour
steps.js
tour.js
conditions.js
const tours = {
onboarding: new Shepherd.Tour(),
advanced: new Shepherd.Tour()
};
Выбор тура:
tours.onboarding.start();
Туры удобно оборачивать в фабрики:
function createTour(config) {
const tour = new Shepherd.Tour(config);
// добавление шагов
return tour;
}
Частые проблемы:
Проверка:
if (!document.querySelector('.selector')) {
console.warn('Элемент не найден');
}
Практики:
Для сложных сценариев:
tour.addStep({
id: 'complex-step',
text: () => {
if (condition) {
return 'Вариант A';
}
return 'Вариант B';
}
});
Интеграция с фреймворками:
if (store.user.isNew) {
tour.start();
}
Минимальная, но масштабируемая организация:
const tour = new Shepherd.Tour({
defaultStepOptions: {...}
});
const steps = [ ... ];
steps.forEach(step => tour.addStep(step));
export default tour;
Такая структура обеспечивает: