Поведение при изменении размеров окна

Shepherd.js предоставляет гибкий механизм управления шагами пользовательского руководства, который учитывает динамические изменения размеров окна браузера. Понимание этих особенностей критически важно для корректного отображения тултипов и сохранения позиционирования относительно целевых элементов на странице.


Автоматическое обновление позиции шагов

Каждый шаг в Shepherd.js создается через объект Shepherd.Tour().addStep(), в котором задается attachTo для привязки тултипа к элементу:

tour.addStep({
  id: 'example-step',
  text: 'Пример шага',
  attachTo: {
    element: '#target-element',
    on: 'bottom'
  }
});

При изменении размеров окна Shepherd.js по умолчанию пересчитывает позицию шага только при активации шага. Это означает, что если шаг уже открыт, а пользователь изменил размер окна, тултип может оставаться в старом положении, что создаёт визуальные несоответствия.

Чтобы исправить это, используется метод step.position(), который можно вызывать вручную при событии resize окна:

window.addEventListener('resize', () => {
  const currentStep = tour.getCurrentStep();
  if (currentStep) {
    currentStep.position();
  }
});

Это гарантирует, что текущий открытый шаг корректно позиционируется после изменения размеров окна.


Параметры позиционирования

Shepherd.js поддерживает несколько направлений для привязки тултипа: top, bottom, left, right, а также auto.

  • auto — шаг автоматически выбирает оптимальное место, чтобы тултип не выходил за пределы видимой области.
  • Статические направления — фиксируют тултип относительно выбранной стороны элемента.

При изменении размеров окна рекомендуется использовать auto, чтобы тултипы адаптировались к новым условиям и не перекрывали другие элементы интерфейса.


Поведение при скрытии или исчезновении элемента

Если элемент, к которому прикреплен шаг, становится скрытым из-за адаптивного дизайна или изменения размеров окна, Shepherd.js не перемещает тултип автоматически. В таких случаях необходимо реализовать проверку видимости:

window.addEventListener('resize', () => {
  const currentStep = tour.getCurrentStep();
  if (currentStep) {
    const target = document.querySelector(currentStep.options.attachTo.element);
    if (!target || target.offsetParent === null) {
      currentStep.hide();
    } else {
      currentStep.position();
    }
  }
});

Использование offsetParent позволяет определить, отображается ли элемент на странице. Если элемент скрыт, шаг можно временно скрыть или пропустить, сохраняя логическую последовательность тура.


Настройка пересчета позиции с debounce

Частые вызовы функции position() при изменении размеров окна могут негативно сказаться на производительности, особенно если в туре много шагов. Для оптимизации применяют debounce:

function debounce(func, wait) {
  let timeout;
  return function() {
    clearTimeout(timeout);
    timeout = setTimeout(() => func.apply(this, arguments), wait);
  };
}

window.addEventListener('resize', debounce(() => {
  const currentStep = tour.getCurrentStep();
  if (currentStep) {
    currentStep.position();
  }
}, 100));

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


Поддержка адаптивного дизайна

Для корректного отображения шагов при изменении размеров окна важно учитывать:

  • Изменение размеров целевых элементов: шаги привязываются к текущим координатам элемента, поэтому при изменении ширины или высоты блока шаги могут смещаться.
  • Медиа-запросы и скрытые элементы: шаги могут исчезать или становиться некорректно позиционированными при переходе между адаптивными состояниями.
  • Изменение ориентации устройства: на мобильных устройствах поворот экрана требует пересчета позиции тултипов.

Использование события resize и вызова position() позволяет учесть все эти изменения и поддерживать визуальную целостность тура.


Рекомендации по работе с динамическим контентом

  • Шаги должны проверять существование и видимость целевых элементов перед вызовом position().
  • Использовать auto позиционирование для адаптации к ограниченной видимой области.
  • Применять debounce при работе с событиями изменения размеров окна, чтобы не перегружать интерфейс.
  • Обновлять позицию после анимаций и переходов интерфейса, которые могут менять расположение элементов.

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