Shepherd.js предоставляет мощный API для создания интерактивных туров, в том числе управление событиями, которые происходят на различных этапах показа шагов. Иногда разработчики сталкиваются с проблемой: события не срабатывают. Разберём причины и решения этой проблемы.
В Shepherd.js события можно разделить на несколько категорий:
События тура Тур генерирует события на глобальном уровне:
start — тур начался.complete — тур успешно завершён.cancel — тур был отменён пользователем.show — показывается текущий шаг.hide — шаг скрыт.События шага Каждый шаг также имеет свои события:
show — шаг отображён.hide — шаг скрыт.complete — шаг выполнен.cancel — шаг отменён.Кнопочные события Shepherd позволяет назначать
обработчики на кнопки шага через свойство action.
Например:
buttons: [
{
text: 'Далее',
action: () => {
console.log('Нажата кнопка Далее');
return tour.next();
}
}
]
Если событие кнопки не срабатывает, важно проверить, что функция
возвращает управление (например,
return tour.next()).
Элемент ещё не существует в DOM Shepherd.js
привязывает шаг к элементу через селектор (attachTo). Если
элемент создаётся динамически после инициализации шага, событие
show или hide может не сработать.
Решение: убедиться, что элемент существует в момент
вызова шага, либо использовать tour.addStep после генерации
элемента.
const step = tour.addStep({
text: 'Пример шага',
attachTo: { element: '#dynamicElement', on: 'bottom' },
when: {
show: () => console.log('Шаг показан')
}
});Неправильное использование свойства
when События шага назначаются через объект
when внутри конфигурации шага. Ошибки типа:
when: {
onShow: () => console.log('Шаг показан') // ❌ неверно
}
Ведут к игнорированию события. Правильная запись:
when: {
show: () => console.log('Шаг показан') // ✅
}Конфликт нескольких обработчиков Если один и тот
же шаг многократно инициализируется с разными функциями
when, более поздние могут перезаписать предыдущие.
Решение: использовать
step.on(event, callback) для добавления обработчиков без
перезаписи:
step.on('show', () => console.log('Дополнительный обработчик'));Возврат промиса или асинхронные действия
Shepherd не ожидает асинхронного завершения шага в обработчике. Если
функция возвращает промис, событие может показаться не сработавшим.
Решение: внутри обработчика использовать
async/await корректно, но без ожидания в самой конфигурации
шага:
when: {
show: async () => {
await fetch('/api/log');
console.log('Лог отправлен');
}
}Неправильная инициализация тура Если тур
создаётся и сразу вызывается start() до того, как добавлены
шаги или назначены события, часть событий может быть пропущена.
Решение: всегда сначала определить все шаги, затем
вызвать tour.start().
when для всех стандартных событий шага
(show, hide, complete,
cancel).step.on()
для динамических действий.onShow или
onHide — библиотека строго использует ключи
show и hide.return tour.next()) и избегать асинхронного кода,
блокирующего шаг.const tour = new Shepherd.Tour({
defaultStepOptions: {
scrollTo: true
}
});
tour.addStep({
id: 'intro',
text: 'Добро пожаловать!',
attachTo: { element: '#intro', on: 'bottom' },
buttons: [
{
text: 'Далее',
action: () => tour.next()
}
],
when: {
show: () => console.log('Шаг intro показан'),
hide: () => console.log('Шаг intro скрыт')
}
});
tour.start();
Этот пример демонстрирует правильное использование всех ключевых событий, привязку к DOM-элементу и работу кнопок.
Если требуется, можно разобрать более сложные сценарии: события при динамически добавленных шагах, глобальные события тура и обработка ошибок в событиях. Все они строятся на тех же принципах: правильная инициализация, существование элементов и корректное указание ключей событий.