Очистка ресурсов

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


Завершение тура и уничтожение экземпляра

Каждый тур в Shepherd.js создается через конструктор Shepherd.Tour. После завершения или отмены тура рекомендуется полностью удалить экземпляр:

const tour = new Shepherd.Tour({
  defaultStepOptions: {
    scrollTo: true,
  },
});

tour.addStep({
  id: 'intro',
  text: 'Добро пожаловать!',
  attachTo: { element: '.header', on: 'bottom' },
  buttons: [
    {
      text: 'Далее',
      action: tour.next,
    },
  ],
});

tour.start();

// Завершение и очистка ресурсов
tour.complete();
tour.destroy();

Ключевые моменты:

  • tour.complete() — завершает текущий тур, вызывая обработчики событий complete у каждого шага.
  • tour.destroy() — освобождает все внутренние ресурсы, удаляет элементы DOM, привязанные к шагам, и снимает обработчики событий.

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


Удаление отдельных шагов

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

tour.addStep({
  id: 'step-to-remove',
  text: 'Этот шаг будет удалён',
  attachTo: { element: '.footer', on: 'top' },
});

tour.removeStep('step-to-remove');

При удалении шага библиотека автоматически:

  • Убирает элемент шага из DOM.
  • Снимает обработчики событий, связанные с этим шагом.
  • Обновляет внутреннюю последовательность шагов тура.

Важно помнить, что удаление шага не останавливает тур, если он уже выполняется, поэтому перед удалением шага стоит убедиться, что тур находится в нужном состоянии.


Очистка обработчиков событий

Каждый шаг в Shepherd.js может иметь собственные события, такие как show, hide, complete, cancel. Для предотвращения утечек памяти и конфликтов нужно очищать эти обработчики:

const step = tour.addStep({
  id: 'example-step',
  text: 'Пример шага с обработчиком',
});

function onShowHandler() {
  console.log('Шаг показан');
}

step.on('show', onShowHandler);

// Удаление обработчика перед уничтожением шага
step.off('show', onShowHandler);

Рекомендации по событиям:

  • Использовать off для удаления обработчиков при динамическом изменении туров.
  • Если тур уничтожается методом destroy(), все внутренние обработчики удаляются автоматически.
  • Для больших приложений, где создаются сотни шагов, явное снятие обработчиков повышает производительность и снижает вероятность ошибок.

Очистка DOM-элементов

Shepherd.js динамически создает контейнеры для подсказок, кнопок и стрелок. При неправильной очистке могут оставаться лишние элементы на странице. После вызова tour.destroy() все элементы удаляются автоматически, но в случае ручного управления шагами важно:

const step = tour.addStep({
  id: 'manual-step',
  text: 'Шаг для демонстрации очистки DOM',
  attachTo: { element: '.manual', on: 'bottom' },
});

step.destroy(); // удаляет DOM, связанный с этим шагом

Особенности:

  • step.destroy() удаляет только DOM текущего шага, не трогая остальные шаги тура.
  • Метод безопасен даже если шаг не был показан.
  • Можно использовать для динамических туров, где шаги создаются и удаляются по событиям пользователя.

Работа с вложенными турами и модальными окнами

При использовании нескольких туров на одной странице или вложенных модальных окон важно очищать все туры одновременно, чтобы не осталось скрытых элементов:

const tour1 = new Shepherd.Tour({ defaultStepOptions: {} });
const tour2 = new Shepherd.Tour({ defaultStepOptions: {} });

tour1.start();
tour2.start();

// Очистка всех туров
[tour1, tour2].forEach(t => {
  t.complete();
  t.destroy();
});

Это предотвращает накладывание подсказок, сохранение старых стилей и лишние слушатели событий.


Практические советы по оптимизации очистки

  1. Всегда вызывать destroy() после завершения тура.
  2. Удалять обработчики событий вручную, если шаги добавляются и удаляются динамически.
  3. Следить за DOM, чтобы не оставались скрытые контейнеры Shepherd.
  4. Использовать идентификаторы шагов, чтобы точно удалять нужные шаги без воздействия на другие.
  5. Для динамических интерфейсов лучше создавать и уничтожать туры на лету, а не пытаться модифицировать один глобальный тур.

Эти практики минимизируют риск утечек памяти и конфликтов интерфейса при сложных сценариях использования Shepherd.js.