Прокрутка в контейнерах

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

Настройка контейнера с прокруткой

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

Пример базовой конфигурации шага:

const tour = new Shepherd.Tour({
  defaultStepOptions: {
    scrollTo: { beh * avior: 'smooth', block: 'center', inline: 'center' }
  }
});

tour.addStep({
  id: 'step1',
  text: 'Элемент находится внутри прокручиваемого контейнера.',
  attachTo: { element: '#nested-element', on: 'bottom' },
  scrollTo: { beh * avior: 'smooth', block: 'center', inline: 'center', container: '#scrollable-container' }
});

tour.start();

Ключевой момент: свойство container внутри scrollTo указывает на элемент-контейнер, а не на window. Shepherd.js корректно вычисляет позицию целевого элемента относительно указанного контейнера и прокручивает его в область видимости.

Варианты прокрутки

  • behavior: управляет плавностью прокрутки ('auto' или 'smooth').
  • block: вертикальное позиционирование элемента ('start', 'center', 'end', 'nearest').
  • inline: горизонтальное позиционирование ('start', 'center', 'end', 'nearest').
  • container: элемент, внутри которого происходит прокрутка.

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

Особенности работы с динамическими контейнерами

Если контейнер с прокруткой создается динамически (например, модальные окна или вкладки), важно убедиться, что контейнер существует в DOM до вызова метода tour.start(). В противном случае шаг не сможет правильно вычислить позицию элемента, и прокрутка не сработает.

Пример динамического контейнера:

document.querySelector('#open-modal').addEventListener('click', () => {
  // Создание модального окна
  const modal = document.createElement('div');
  modal.id = 'modal-container';
  modal.style.overflow = 'auto';
  modal.style.height = '300px';
  document.body.appendChild(modal);

  const tour = new Shepherd.Tour({ defaultStepOptions: { scrollTo: { beh * avior: 'smooth', container: '#modal-container' } } });

  tour.addStep({
    id: 'modal-step',
    text: 'Элемент внутри модального окна.',
    attachTo: { element: '#modal-element', on: 'top' }
  });

  tour.start();
});

Совместимость с nested-scroll контейнерами

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

function getScrollContainer(element) {
  while (element) {
    const overflowY = window.getComputedStyle(element).overflowY;
    if (overflowY === 'auto' || overflowY === 'scroll') return element;
    element = element.parentElement;
  }
  return window;
}

const container = getScrollContainer(document.querySelector('#deep-element'));

tour.addStep({
  id: 'deep-step',
  text: 'Глубоко вложенный элемент.',
  attachTo: { element: '#deep-element', on: 'top' },
  scrollTo: { beh * avior: 'smooth', container }
});

Прокрутка при смене шага

Shepherd.js автоматически обрабатывает прокрутку при переходе между шагами, если свойство scrollTo определено в defaultStepOptions. Это особенно удобно для длинных страниц или сложных интерфейсов с множеством вложенных блоков.

Советы по оптимизации

  • Использовать scrollTo: { beh * avior: 'smooth' } для плавной анимации, чтобы пользователь не терял контекст.
  • Всегда проверять, что контейнер существует в DOM перед запуском тура.
  • Для многоуровневых прокруток использовать вычисление ближайшего scroll-контейнера, чтобы избежать конфликтов.
  • При необходимости отключать автоматическую прокрутку для отдельных шагов с scrollTo: false.

Примеры практического применения

  1. Сайдбар с прокруткой: элементы меню, скрытые за прокруткой, автоматически выводятся в видимую область при активации шага.
  2. Модальные окна: шаги корректно привязываются к контенту внутри модальных окон, даже если они скрыты по умолчанию.
  3. Вложенные вкладки: Shepherd.js позволяет прокручивать содержимое активной вкладки, не трогая другие.

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