Кнопка Cancel в библиотеке Shepherd.js предназначена для немедленного прерывания текущего тура. В отличие от навигационных кнопок (Next, Back), она завершает сценарий полностью, сбрасывая текущее состояние и скрывая все активные шаги.
Основные задачи кнопки:
При нажатии кнопки Cancel происходит:
cancelМетод, который вызывается внутренне:
tour.cancel();
Это означает, что добавление кнопки Cancel по сути является привязкой к этому методу.
Кнопка задаётся в массиве buttons внутри конфигурации
шага:
const tour = new Shepherd.Tour();
tour.addStep({
id: 'example-step',
text: 'Описание шага',
buttons: [
{
text: 'Cancel',
action: () => tour.cancel()
}
]
});
Ключевые свойства кнопки:
text — отображаемый текстaction — функция, выполняемая при нажатииShepherd передаёт в action контекст текущего шага
(this), что позволяет не ссылаться напрямую на
tour:
buttons: [
{
text: 'Cancel',
action: function () {
this.cancel();
}
}
]
Такой подход особенно полезен при создании переиспользуемых конфигураций шагов.
Кнопке можно задать CSS-классы через свойство
classes:
buttons: [
{
text: 'Cancel',
action: () => tour.cancel(),
classes: 'shepherd-button-secondary'
}
]
Часто используется:
Порядок кнопок определяется порядком в массиве:
buttons: [
{
text: 'Cancel',
action: () => tour.cancel()
},
{
text: 'Next',
action: () => tour.next()
}
]
Практика:
Событие cancel позволяет выполнять дополнительную логику
при отмене тура:
tour.on('cancel', () => {
console.log('Тур был отменён');
});
Возможные сценарии:
Важно различать два сценария завершения тура:
| Действие | Метод | Событие | Значение |
|---|---|---|---|
| Отмена | cancel() |
cancel |
Пользователь прервал |
| Завершение | complete() |
complete |
Тур пройден полностью |
Это различие критично для логики приложения.
Кнопка Cancel может добавляться не на все шаги:
buttons: [
{
text: 'Cancel',
action: () => tour.cancel(),
classes: 'shepherd-button-secondary',
disabled: false
}
]
Или динамически:
if (shouldAllowCancel) {
stepConfig.buttons.push({
text: 'Cancel',
action: () => tour.cancel()
});
}
Вместо прямого вызова tour.cancel() можно внедрить
промежуточную логику:
buttons: [
{
text: 'Cancel',
action: () => {
if (confirm('Прервать тур?')) {
tour.cancel();
}
}
}
]
Другие примеры:
Кнопка Cancel — не единственный способ завершения тура. Метод
cancel() можно вызвать из любого места:
document.querySelector('#exit-tour').addEventListener('click', () => {
tour.cancel();
});
Это позволяет:
Если включён затемняющий слой (useModalOverlay: true),
кнопка Cancel:
Дополнительно можно разрешить отмену кликом вне шага:
const tour = new Shepherd.Tour({
useModalOverlay: true,
exitOnEsc: true
});
По умолчанию поддерживается отмена через клавишу Escape:
exitOnEsc: true
Это эквивалентно нажатию кнопки Cancel.
Если шаг содержит асинхронную логику (например, загрузку данных),
вызов cancel():
Пример:
let isCancelled = false;
tour.on('cancel', () => {
isCancelled = true;
});
async function loadData() {
const data = await fetch('/api/data');
if (isCancelled) return;
// обработка данных
}
После вызова cancel() тур можно запустить снова:
tour.start();
Но состояние шагов сбрасывается:
Можно сохранить текущий шаг:
let currentStepId;
tour.on('show', (event) => {
currentStepId = event.step.id;
});
tour.on('cancel', () => {
localStorage.setItem('tourStep', currentStepId);
});
Позже:
const savedStep = localStorage.getItem('tourStep');
if (savedStep) {
tour.show(savedStep);
}
Кнопка Cancel не должна доминировать визуально
Использование понятных текстов:
Наличие подтверждения при критичных сценариях
Возможность повторного запуска тура
1. Отсутствие действия
{
text: 'Cancel'
}
Кнопка не работает без action.
2. Неправильный контекст
action: function () {
tour.cancel(); // может быть недоступен
}
Решение — использовать this.cancel().
3. Смешивание complete и cancel
Использование complete() вместо cancel() и
наоборот приводит к логическим ошибкам в аналитике и пользовательском
опыте.
{
text: 'Cancel',
action: function () {
this.cancel();
},
classes: 'shepherd-button-secondary'
}
Эта конфигурация является базовой и может быть расширена в зависимости от требований интерфейса и бизнес-логики.