Условное отображение шагов

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


Определение условий для шагов

Каждый шаг в Shepherd.js может содержать параметр when или функцию, определяющую, будет ли шаг отображён. Основная идея заключается в проверке состояния приложения перед показом шага. Простейший способ реализации — использование функции beforeShowPromise:

const tour = new Shepherd.Tour({
  defaultStepOptions: {
    classes: 'shepherd-theme-arrows',
    scrollTo: true
  }
});

tour.addStep({
  id: 'conditional-step',
  text: 'Этот шаг отображается только если пользователь вошёл в систему',
  attachTo: { element: '#loginButton', on: 'bottom' },
  beforeShowPromise: () => {
    return new Promise((resolve, reject) => {
      if (userIsLoggedIn()) {
        resolve();
      } else {
        reject();
      }
    });
  }
});

В этом примере шаг будет отображён только если функция userIsLoggedIn() возвращает true. Если условие не выполнено, шаг будет пропущен, а тур продолжится с последующего шага.


Использование advanceOn для динамических шагов

Параметр advanceOn позволяет переходить к следующему шагу при выполнении определённого действия. Его можно комбинировать с условием, чтобы шаг отображался только при нужных обстоятельствах:

tour.addStep({
  id: 'dynamic-step',
  text: 'Этот шаг отображается, если элемент видим на странице',
  attachTo: { element: '#dynamicElement', on: 'top' },
  advanceOn: {
    selector: '#dynamicElement',
    event: 'click'
  },
  beforeShowPromise: () => {
    if (document.querySelector('#dynamicElement')) {
      return Promise.resolve();
    } else {
      return Promise.reject();
    }
  }
});

Таким образом, шаг становится контекстно-зависимым, реагируя на наличие элемента или других условий в DOM.


Условная последовательность шагов

Для построения сложной логики отображения шагов удобно использовать массив шагов с функцией-фильтром перед запуском тура:

const steps = [
  { id: 'step1', text: 'Обязательный шаг' },
  { id: 'step2', text: 'Шаг для авторизованных', condition: () => userIsLoggedIn() },
  { id: 'step3', text: 'Шаг для гостей', condition: () => !userIsLoggedIn() }
];

steps.forEach(step => {
  if (!step.condition || step.condition()) {
    tour.addStep(step);
  }
});

Преимущество этого подхода в том, что тур создаётся динамически, а лишние шаги не добавляются в последовательность.


Отложенное добавление шагов

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

function addConditionalStep() {
  if (shouldShowStep()) {
    tour.addStep({
      id: 'late-step',
      text: 'Этот шаг добавлен динамически',
      attachTo: { element: '#lateElement', on: 'bottom' }
    });
  }
}

tour.on('show', () => {
  addConditionalStep();
});

Такой подход полезен для многоступенчатых форм или интерактивных интерфейсов, где шаги появляются только после определённых действий.


Комбинация с пользовательскими условиями

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

tour.addStep({
  id: 'async-step',
  text: 'Шаг отображается после проверки на сервере',
  beforeShowPromise: () => {
    return fetch('/api/check-feature')
      .then(response => response.json())
      .then(data => {
        if (data.enabled) {
          return Promise.resolve();
        } else {
          return Promise.reject();
        }
      });
  }
});

Это позволяет интегрировать тур с бизнес-логикой приложения и управлять шагами в зависимости от внешних условий.


Рекомендации по организации условных шагов

  • Ясная структура шагов: при большом туре лучше использовать объект с ключами condition, text, attachTo, чтобы легко фильтровать шаги.
  • Использовать beforeShowPromise: основной способ для асинхронных проверок.
  • Избегать блокировки тура: при отказе шаг должен корректно пропускаться, чтобы последовательность оставалась логичной.
  • Локальные переменные состояния: удобно хранить состояния шагов в объекте, чтобы избежать повторных проверок.

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