Shepherd.js — библиотека для создания интерактивных туров по
интерфейсу, где каждый шаг (step) управляется объектом с
параметрами конфигурации. Стратегия обновления отвечает за корректное
управление состоянием шагов при изменениях DOM, навигации между шагами и
изменении размеров элементов на странице. Без правильной стратегии
обновления тур может вести себя некорректно: подсказки будут смещаться,
появляться в неправильных местах или вовсе исчезать.
Shepherd.js предоставляет возможность автоматически отслеживать
целевой элемент через свойство attachTo. Основной принцип:
когда целевой элемент динамически изменяется или перестраивается в DOM,
подсказка должна автоматически адаптироваться к новой позиции. Для этого
используется метод updateStepOptions и внутренние слушатели
событий изменения размеров и положения элемента.
Пример конфигурации шага с автоматическим отслеживанием:
const tour = new Shepherd.Tour({
defaultStepOptions: {
scrollTo: true,
popperOptions: {
modifiers: [{ name: 'offset', options: { offset: [0, 10] } }]
}
}
});
tour.addStep({
id: 'example-step',
text: 'Это динамический элемент',
attachTo: { element: '#dynamic-element', on: 'bottom' },
when: {
show: () => console.log('Шаг показан'),
hide: () => console.log('Шаг скрыт')
}
});
При изменении размеров элемента библиотека автоматически
пересчитывает позицию, если включены слушатели resize и
scroll.
updateStepOptions(stepId, options)
— позволяет изменить параметры существующего шага без пересоздания.
Ключевые моменты:
show() и hide() —
повторный вызов метода show() автоматически пересчитывает
позицию и адаптирует подсказку к текущему DOM.
Пример динамического изменения шага:
tour.updateStepOptions('example-step', {
text: 'Новый текст шага',
attachTo: { element: '#new-element', on: 'top' }
});
tour.show('example-step');
Для динамических интерфейсов критично отслеживать изменения DOM с
помощью MutationObserver. Shepherd.js не создает встроенный
наблюдатель за всеми элементами, поэтому рекомендуется интегрировать
такой наблюдатель вручную для элементов, к которым привязаны шаги.
Пример использования MutationObserver для обновления
шага:
const targetNode = document.getElementById('dynamic-element');
const observer = new MutationObserver(() => {
tour.getById('example-step').updateStepOptions({
attachTo: { element: '#dynamic-element', on: 'bottom' }
});
});
observer.observe(targetNode, { attributes: true, childList: true, subtree: true });
Подсказки Shepherd.js используют библиотеку Popper.js для
позиционирования. Это обеспечивает автоматическое перемещение подсказки
при изменении размеров окна или прокрутке страницы. Важно правильно
настроить опцию scrollTo, чтобы элемент оставался в зоне
видимости:
tour.addStep({
id: 'scroll-step',
text: 'Следующий шаг после прокрутки',
attachTo: { element: '#scroll-target', on: 'top' },
scrollTo: { beh * avior: 'smooth', block: 'center' }
});
Для сложных интерфейсов иногда требуется вручную управлять обновлением шагов. Для этого можно использовать события Shepherd.js:
show — вызывается при показе шага,
позволяет вычислить позицию и применить кастомные стили.hide — скрытие шага, освобождает
ресурсы и отключает слушатели.cancel и complete —
позволяют корректно завершить тур и очистить динамически добавленные
шаги.Пример кастомного пересчета позиции:
tour.on('show', (event) => {
const step = event.step;
const target = document.querySelector('#dynamic-element');
if (target) {
step.updateStepOptions({ attachTo: { element: '#dynamic-element', on: 'right' } });
}
});
Shepherd.js хранит состояние каждого шага: активный, скрытый, завершенный. Стратегия обновления должна учитывать:
При большом количестве динамических шагов важно минимизировать количество пересчетов позиции:
MutationObserver только для необходимых
элементов.resize и
scroll.updateStepOptions только при реальном
изменении целевого элемента.Эта стратегия обеспечивает стабильное отображение подсказок даже в сложных и динамических интерфейсах, предотвращает смещение и потерю контекста при изменении DOM и позволяет управлять туром гибко и предсказуемо.