Стратегия обновления

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

Для динамических интерфейсов критично отслеживать изменения 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 хранит состояние каждого шага: активный, скрытый, завершенный. Стратегия обновления должна учитывать:

  • Неактивные шаги не пересчитываются.
  • Активный шаг должен автоматически реагировать на изменения DOM.
  • Обновление шагов не должно создавать дубликаты подсказок.

Оптимизация производительности

При большом количестве динамических шагов важно минимизировать количество пересчетов позиции:

  • Использовать MutationObserver только для необходимых элементов.
  • Ограничивать обработку событий resize и scroll.
  • Вызывать updateStepOptions только при реальном изменении целевого элемента.

Эта стратегия обеспечивает стабильное отображение подсказок даже в сложных и динамических интерфейсах, предотвращает смещение и потерю контекста при изменении DOM и позволяет управлять туром гибко и предсказуемо.