Условные маршруты

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


Определение условного маршрута

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

  1. Использование функции beforeShowPromise Каждому шагу можно задать функцию beforeShowPromise, которая возвращает промис. Если промис выполняется успешно, шаг отображается, иначе он пропускается.

    Пример:

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

    Ключевой момент: beforeShowPromise позволяет проверять любые условия — от состояния приложения до данных, загруженных с сервера.


Программное управление переходами

Помимо условной логики на уровне шагов, можно управлять маршрутом тура через события cancel, complete и show. Это дает возможность перенаправлять пользователя на другой шаг при выполнении определённых условий.

tour.on('show', function(step) {
  if (step.id === 'step-1' && !user.hasProfile()) {
    tour.show('step-3'); // Пропускаем шаг 2
  }
});

Особенности подхода:

  • tour.show(stepId) немедленно показывает указанный шаг.
  • Этот метод полезен для маршрутов с несколькими ветвями, где шаги могут зависеть от данных пользователя.
  • Не рекомендуется вызывать внутри beforeShowPromise, так как это может нарушить последовательность промисов.

Ветвление шагов через кастомные условия

Для более сложных сценариев можно создать ветвление на основе объектов конфигурации:

const stepsConfig = [
  { id: 'step-1', text: 'Начало тура' },
  { id: 'step-2', text: 'Дополнительный шаг', condition: () => user.isAdmin() },
  { id: 'step-3', text: 'Финальный шаг' }
];

stepsConfig.forEach(step => {
  tour.addStep({
    id: step.id,
    text: step.text,
    beforeShowPromise: () => step.condition ? step.condition() ? Promise.resolve() : Promise.reject() : Promise.resolve()
  });
});

Преимущества такого подхода:

  • Четкая структура шагов и условий.
  • Легкость расширения и изменения логики ветвления.
  • Возможность объединять синхронные и асинхронные условия.

Условные маршруты с использованием when и advanceOn

Для интеграции с пользовательскими действиями используется опция advanceOn, которая позволяет переходить к следующему шагу при выполнении события на DOM-элементе. В сочетании с условием это создаёт динамический маршрут:

tour.addStep({
  id: 'step-action',
  text: 'Нажмите кнопку, чтобы продолжить',
  attachTo: { element: '#action-btn', on: 'right' },
  advanceOn: { selector: '#action-btn', event: 'click' },
  beforeShowPromise: function() {
    return someAsyncCheck() ? Promise.resolve() : Promise.reject();
  }
});

Заметка: advanceOn и beforeShowPromise можно комбинировать для проверки состояния перед разрешением перехода.


Управление ветвями через методы Shepherd.Tour

Shepherd.js предоставляет несколько методов для динамического управления шагами:

  • tour.next() — переход к следующему шагу.
  • tour.back() — возврат к предыдущему шагу.
  • tour.show(stepId) — переход к определённому шагу.
  • tour.cancel() — завершение тура.

Используя эти методы в сочетании с событиями (show, complete, cancel), можно реализовать сложные сценарии условного маршрута:

tour.on('complete', function() {
  if (user.hasCompletedTutorial()) {
    tour.show('bonus-step');
  }
});

Лучшие практики для условных маршрутов

  1. Минимизировать вложенность промисов — использовать async/await внутри beforeShowPromise.
  2. Четко именовать шаги — облегчает управление маршрутами через tour.show(stepId).
  3. Использовать централизованную конфигурацию шагов — особенно для приложений с разветвлённой логикой.
  4. Проверять совместимость с мобильными интерфейсами — условия могут зависеть от размеров экрана или доступности элементов.

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