Уничтожение контроллера

Экземпляр ScrollMagic.Controller управляет всеми сценами (Scene), связанными с прокруткой страницы. В процессе работы приложения контроллер накапливает внутренние ссылки, обработчики событий и данные о сценах. При динамическом изменении интерфейса (SPA, повторная инициализация компонентов, переходы между страницами) требуется корректно освобождать ресурсы, чтобы избежать утечек памяти и конфликтов поведения.

Уничтожение контроллера — это процесс полного отключения всех связанных сцен, удаления обработчиков событий и очистки внутренних структур.


Метод destroy()

Основной способ уничтожения контроллера — вызов метода:

controller.destroy(resetScenes);

Параметр resetScenes

  • true — все сцены будут сброшены в исходное состояние
  • false — сцены сохранят текущее состояние

Пример:

controller.destroy(true);

Поведение при уничтожении

При вызове destroy() происходит:

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

Если указан resetScenes = true, дополнительно:

  • сцены возвращаются в начальное состояние
  • удаляются эффекты закрепления (pin)
  • отменяются анимации и классы

Разница между destroy(true) и destroy(false)

destroy(true)

Используется, когда необходимо полностью очистить всё поведение:

  • интерфейс возвращается в исходное состояние
  • DOM очищается от всех изменений ScrollMagic
  • безопасен для повторной инициализации

destroy(false)

Применяется, если требуется:

  • сохранить текущий визуальный результат
  • избежать «скачков» интерфейса

Однако:

  • сцены остаются в текущем состоянии
  • возможны побочные эффекты при повторном создании контроллера

Уничтожение сцен перед контроллером

Хотя controller.destroy() автоматически обрабатывает сцены, в сложных случаях рекомендуется вручную уничтожать сцены:

scene.destroy(true);
controller.destroy(true);

Причины:

  • контроль порядка очистки
  • предотвращение конфликтов анимаций
  • точечное управление состоянием

Повторная инициализация контроллера

После уничтожения возможно создание нового контроллера:

controller = new ScrollMagic.Controller();

Важно учитывать:

  • старые сцены не должны использоваться повторно
  • требуется создать новые экземпляры Scene
  • необходимо заново привязать анимации и обработчики

Использование в SPA (Single Page Application)

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

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

function initScrollMagic() {
    controller = new ScrollMagic.Controller();

    scene = new ScrollMagic.Scene({ triggerElement: "#trigger" })
        .setClassToggle("#animate", "active")
        .addTo(controller);
}

function destroyScrollMagic() {
    if (controller) {
        controller.destroy(true);
        controller = null;
    }
}

Утечки памяти и их предотвращение

Если контроллер не уничтожается:

  • обработчики прокрутки продолжают работать
  • сцены остаются в памяти
  • DOM-ссылки не освобождаются

Это приводит к:

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

Правильное уничтожение устраняет эти проблемы.


Особенности работы с плагинами

Если используются плагины (например, GSAP-анимации):

  • destroy(true) не всегда полностью удаляет сторонние эффекты
  • требуется дополнительная очистка анимаций

Пример с GSAP:

scene.destroy(true);
TweenMax.killTweensOf(element);

Проверка состояния контроллера

После уничтожения контроллер не должен использоваться:

if (!controller) {
    // безопасно создать новый
}

Повторное использование уничтоженного экземпляра может привести к ошибкам.


Частые ошибки

1. Повторный вызов destroy()

controller.destroy();
controller.destroy(); // ошибка или непредсказуемое поведение

2. Использование сцен после уничтожения

controller.destroy();
scene.addTo(controller); // некорректно

3. Игнорирование resetScenes

controller.destroy(false);

Может привести к зависшим стилям и классам.


Взаимодействие с DOM

При уничтожении с resetScenes = true:

  • удаляются inline-стили
  • восстанавливаются позиции элементов
  • снимаются классы, добавленные через setClassToggle

Если false:

  • DOM остаётся модифицированным
  • возможны конфликты при повторной инициализации

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

  • всегда использовать destroy(true) при удалении контроллера
  • очищать сцены вручную в сложных проектах
  • избегать повторного использования старых объектов
  • синхронизировать уничтожение с жизненным циклом компонентов
  • учитывать сторонние анимации и очищать их отдельно

Диагностика проблем

Признаки неправильного уничтожения:

  • анимации продолжаются после удаления компонента
  • события прокрутки срабатывают несколько раз
  • элементы остаются закреплёнными (pin)
  • стили не возвращаются в исходное состояние

Отладка:

console.log(controller);

После уничтожения:

controller === null // должно быть true

Внутренняя реализация

Метод destroy():

  • удаляет ссылку на контейнер прокрутки
  • очищает массив _sceneObjects
  • отключает обработчики scroll и resize
  • обнуляет внутренние параметры

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


Контроль жизненного цикла

Корректная схема работы:

  1. Создание контроллера
  2. Добавление сцен
  3. Работа с прокруткой
  4. Уничтожение сцен
  5. Уничтожение контроллера
  6. Очистка ссылок

Нарушение этой последовательности часто приводит к трудноуловимым багам.