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

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

В обычной последовательности шаги задаются статически через атрибуты data-intro и data-step. Для динамических сценариев требуется управлять шагами программно.

const steps = [
  { element: '#step1', intro: 'Первый шаг всегда отображается' },
  { element: '#step2', intro: 'Этот шаг будет показан только при условии', condition: () => userLoggedIn },
  { element: '#step3', intro: 'Финальный шаг' }
];

В приведённом примере шаг с #step2 будет показан только если переменная userLoggedIn равна true. Такие условия позволяют избегать показа ненужных инструкций, улучшая UX.


Создание и фильтрация шагов программно

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

const intro = introJs();

const allSteps = [
  { element: '#menu', intro: 'Меню приложения' },
  { element: '#profile', intro: 'Профиль пользователя', condition: () => userLoggedIn },
  { element: '#help', intro: 'Раздел помощи' }
];

// Фильтруем шаги по условию
const filteredSteps = allSteps.filter(step => !step.condition || step.condition());

intro.setOptions({ steps: filteredSteps });
intro.start();

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


Встроенные события и управление потоком

Intro.js предоставляет события для контроля показа шагов. Основные из них:

  • onbeforechange(targetElement) – вызывается перед отображением нового шага. Можно отменить переход, вернув false.
  • onchange(targetElement) – вызывается после отображения шага.
  • onafterchange(targetElement) – после завершения анимации показа шага.

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

intro.onbeforechange(function(targetElement) {
  if (targetElement.id === 'profile' && !userLoggedIn) {
    return false; // пропустить шаг, если пользователь не авторизован
  }
});

Условные шаги на основе состояния DOM

Иногда условие зависит не от переменных, а от наличия элементов на странице. Intro.js позволяет проверять DOM перед добавлением шагов:

const steps = [];

if (document.querySelector('#notifications')) {
  steps.push({ element: '#notifications', intro: 'Раздел уведомлений' });
}

steps.push({ element: '#footer', intro: 'Подвал сайта' });

introJs().setOptions({ steps }).start();

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


Динамическое изменение шагов во время прохождения

В некоторых сценариях необходимо изменять последовательность шагов во время работы интро. Для этого можно использовать методы nextStep() и addStep():

introJs().start();

intro.onafterchange(function(targetElement) {
  if (targetElement.id === 'menu' && userHasSettings) {
    intro.addStep({
      element: '#settings',
      intro: 'Дополнительный шаг для настроек'
    });
  }
});

Этот приём позволяет реагировать на действия пользователя и добавлять новые шаги без перезапуска интро.


Практические рекомендации

  • Состояния приложения. Все условия должны учитывать актуальное состояние данных и DOM, чтобы шаги не показывались для несуществующих элементов.
  • Фильтрация шагов. Перед запуском лучше фильтровать массив шагов, чтобы исключить лишние шаги, чем пытаться пропустить их во время показа.
  • События Intro.js. Использовать события onbeforechange и onafterchange для динамических изменений порядка шагов и их видимости.
  • Тестирование. Проверять все комбинации условий, особенно при сложных интерактивных интерфейсах, чтобы последовательность шагов оставалась логичной.

Примеры комплексного условного интро

const intro = introJs();

const steps = [
  { element: '#dashboard', intro: 'Главная панель' },
  { element: '#analytics', intro: 'Аналитика', condition: () => userRole === 'admin' },
  { element: '#messages', intro: 'Сообщения', condition: () => messages.length > 0 },
  { element: '#help', intro: 'Раздел помощи' }
];

const filteredSteps = steps.filter(step => !step.condition || step.condition());

intro.setOptions({ steps: filteredSteps });

intro.onbeforechange(targetElement => {
  if (targetElement.id === 'analytics' && !userRole === 'admin') {
    return false; // дополнительная защита
  }
});

intro.start();

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