Уничтожение экземпляра dragula

При работе с библиотекой Dragula крайне важно корректно управлять жизненным циклом её экземпляров. Одним из ключевых аспектов является уничтожение экземпляра после завершения работы с элементами, чтобы избежать утечек памяти, некорректного поведения интерфейса и конфликтов при повторной инициализации.


Метод destroy()

Каждый экземпляр Dragula создаётся функцией dragula(containers, options), где containers — массив DOM-элементов, а options — объект конфигурации. Для уничтожения экземпляра используется метод:

const drake = dragula([container1, container2], { /* options */ });

// В какой-то момент
drake.destroy();

Особенности метода destroy():

  • Удаляет все обработчики событий, которые Dragula добавила к контейнерам и элементам.
  • Возвращает DOM-элементы в исходное состояние, если ранее были применены временные классы (gu-mirror, gu-hide, gu-transit).
  • Делает экземпляр неактивным, повторные операции перетаскивания через этот объект станут невозможны.
  • Не удаляет сами DOM-элементы контейнеров или элементов.

Очистка временных элементов

Во время перетаскивания Dragula создаёт вспомогательные элементы:

  • gu-mirror — элемент-копия перетаскиваемого объекта.
  • gu-transit — класс, добавляемый на оригинальный элемент на время перетаскивания.
  • gu-hide — скрывает элемент в исходном контейнере, пока он переносится.

Метод destroy() автоматически очищает эти элементы и снимает классы, чтобы не оставалось “мусора” в DOM.

drake.destroy(); 
// После вызова не останется gu-mirror и gu-transit

Отписка от событий

Dragula предоставляет обширный API для событий:

drake.on('drag', (el) => { /* ... */ });
drake.on('drop', (el, target, source, sibling) => { /* ... */ });

После вызова destroy():

  • Все привязанные обработчики удаляются.
  • Любые последующие события через экземпляр drake не будут вызваны.
  • Для повторного использования контейнеров необходимо создавать новый экземпляр Dragula.

Практические сценарии уничтожения

  1. Динамическая смена контейнеров:

Если интерфейс позволяет пользователю изменять набор контейнеров или полностью обновлять список элементов:

drake.destroy();
const newDrake = dragula([newContainer1, newContainer2]);
  1. Условное отключение Drag & Drop:

Для временного отключения функционала без удаления DOM:

if (disableDrag) {
    drake.destroy();
}
  1. Массовая очистка при переходе на другой раздел:

При SPA или одностраничных приложениях важно очищать все экземпляры:

allDrakes.forEach(d => d.destroy());
allDrakes = [];

Рекомендации по использованию

  • Никогда не оставлять экземпляры Dragula без вызова destroy() при удалении контейнеров из DOM. Это предотвращает утечки памяти и ошибки в будущем.
  • Не пытаться повторно использовать экземпляр после вызова destroy(); создаётся новый объект.
  • Если требуется временно отключить перетаскивание, можно использовать методы drake.cancel(true) или drake.off(event, handler) для частичной отписки, но полное уничтожение обеспечивает чистоту и безопасность кода.

Взаимодействие с другими методами

Метод destroy() является завершающим этапом работы с экземпляром и взаимодействует с другими методами Dragula следующим образом:

  • drake.remove() — удаляет элемент из контейнера, но не уничтожает экземпляр.
  • drake.cancel() — прерывает текущее перетаскивание, но не отключает Dragula.
  • drake.destroy() — отключает полностью и снимает все привязки событий.

Таким образом, destroy() является ключевым инструментом управления жизненным циклом Dragula, обеспечивая стабильность интерфейса и предотвращение накопления ненужных обработчиков и временных элементов.