Жизненный цикл компонента и тура

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

Ключевые сущности:

  • Tour — контейнер для шагов и глобальных настроек
  • Step — отдельный шаг с привязкой к DOM-элементу
  • Event system — механизм подписки на изменения состояния

Состояния тура

Тур последовательно проходит несколько базовых состояний:

  1. Инициализация

    • Создание экземпляра Shepherd.Tour
    • Добавление шагов
    • Настройка опций (модальность, классы, поведение кнопок)
  2. Готовность (idle)

    • Тур создан, но не запущен
    • DOM может еще не содержать целевых элементов
  3. Запуск (start)

    • Вызов tour.start()
    • Инициализация первого шага
    • Применение overlay и фокуса
  4. Активное выполнение

    • Отображение шагов
    • Переходы между шагами (next, back)
    • Обработка пользовательских действий
  5. Завершение

    • Явное (complete)
    • Принудительное (cancel)

Инициализация тура

Создание тура задаёт основу жизненного цикла:

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

Особенности этапа:

  • Конфигурация применяется ко всем шагам
  • DOM-элементы могут быть ещё не готовы
  • Тур не влияет на интерфейс до запуска

Добавление шагов и их жизненный цикл

Каждый шаг имеет собственный жизненный цикл, вложенный в цикл тура:

tour.addStep({
  id: 'example-step',
  text: 'Описание шага',
  attachTo: {
    element: '.example',
    on: 'bottom'
  },
  buttons: [
    {
      text: 'Далее',
      action: tour.next
    }
  ]
});

Этапы жизни шага:

  1. Создание (конфигурация)
  2. Подготовка (поиск DOM-элемента)
  3. Отображение
  4. Взаимодействие
  5. Скрытие/уничтожение

События жизненного цикла

Shepherd.js предоставляет мощную систему событий:

События тура

  • start — тур запущен
  • complete — успешно завершён
  • cancel — отменён
  • show — показ шага
  • hide — скрытие шага

Пример подписки:

tour.on('start', () => {
  console.log('Тур начался');
});

tour.on('complete', () => {
  console.log('Тур завершён');
});

События шага

step.on('show', () => {
  console.log('Шаг показан');
});

Практическое применение:

  • Логирование
  • Аналитика
  • Синхронизация с backend
  • Управление состоянием UI

Запуск тура

Метод запуска:

tour.start();

Происходит:

  • Проверка шагов
  • Установка текущего шага
  • Добавление overlay
  • Блокировка взаимодействия с фоном (при необходимости)

Особенность: если элемент шага отсутствует в DOM, шаг может не отобразиться — важно учитывать асинхронную загрузку интерфейса.


Переходы между шагами

Shepherd управляет переходами через методы:

tour.next();
tour.back();
tour.show('step-id');

Во время перехода:

  1. Текущий шаг скрывается
  2. Новый шаг инициализируется
  3. Применяется позиционирование
  4. Вызываются события

Асинхронность и ожидание DOM

Частая проблема — элементы ещё не отрисованы.

Решение — использовать beforeShowPromise:

tour.addStep({
  id: 'async-step',
  text: 'Асинхронный шаг',
  attachTo: {
    element: '.dynamic-element',
    on: 'bottom'
  },
  beforeShowPromise: function () {
    return new Promise(resolve => {
      setTimeout(resolve, 500);
    });
  }
});

Назначение:

  • ожидание загрузки данных
  • ожидание появления DOM-элемента
  • синхронизация с анимациями

Завершение и очистка

Успешное завершение

tour.complete();
  • удаляются все шаги
  • снимается overlay
  • вызываются события

Отмена тура

tour.cancel();
  • аналогично complete, но с другим событием
  • используется при прерывании пользователем

Уничтожение и повторное использование

Shepherd не требует полного уничтожения объекта тура:

  • можно повторно вызывать start()
  • шаги сохраняются

Однако при сложной логике рекомендуется:

  • пересоздавать тур
  • очищать обработчики событий

Управление состоянием приложения

Жизненный цикл тура часто связан с состоянием приложения:

Типичные сценарии:

  • запуск после авторизации
  • запуск при первом входе
  • запуск при достижении определённого состояния UI

Пример:

if (!localStorage.getItem('tourSeen')) {
  tour.start();
  localStorage.setItem('tourSeen', true);
}

Работа с динамическими интерфейсами

В SPA (React, Vue и др.) жизненный цикл тура должен учитывать:

  • перерисовку компонентов
  • удаление DOM-узлов
  • смену маршрутов

Подходы:

  • запуск тура после mount
  • отслеживание роутов
  • повторная привязка шагов

Ошибки жизненного цикла

Наиболее распространённые:

1. Элемент не найден

  • шаг не отображается
  • решение: beforeShowPromise

2. Тур запускается слишком рано

  • DOM не готов
  • решение: запуск после рендера

3. Потеря состояния при переходе

  • SPA перерисовывает интерфейс
  • решение: хранение состояния шага

Расширение жизненного цикла

Shepherd позволяет внедрять собственную логику:

  • кастомные кнопки
  • пользовательские обработчики
  • интеграция с аналитикой

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

buttons: [
  {
    text: 'Далее',
    action: () => {
      console.log('Переход');
      tour.next();
    }
  }
]

Взаимодействие с пользователем

Жизненный цикл тура напрямую связан с UX:

  • блокировка фона
  • подсветка элементов
  • управление фокусом

Ключевые настройки:

  • useModalOverlay
  • scrollTo
  • canClickTarget

Оптимизация жизненного цикла

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

  • минимизировать количество шагов
  • избегать привязки к нестабильным DOM-элементам
  • использовать события вместо жёсткой логики
  • контролировать асинхронность

Связь между шагами и состоянием тура

Каждый шаг зависит от:

  • текущего состояния тура
  • доступности DOM
  • действий пользователя

Цикл шага:

  1. Подготовка
  2. Проверка условий
  3. Отображение
  4. Взаимодействие
  5. Завершение

Итоговая модель жизненного цикла

Tour:

init → start → step transitions → complete/cancel

Step:

create → prepare → show → interact → hide → destroy

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