Управление жизненным циклом

Dragula — это легковесная библиотека для реализации перетаскивания элементов (drag-and-drop) в веб-приложениях на JavaScript. Основной способ подключения — через npm или CDN.

Установка через npm:

npm install dragula

Подключение через CDN:

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/dragula/3.7.3/dragula.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/dragula/3.7.3/dragula.min.js"></script>

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


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

Создание экземпляра Dragula выполняется через вызов функции dragula(). В качестве аргумента передается массив контейнеров:

const containers = [document.getElementById('left'), document.getElementById('right')];
const drake = dragula(containers);

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

  • moves — функция, определяющая, можно ли перемещать конкретный элемент.
  • accepts — функция, ограничивающая возможность перемещения элемента в определенный контейнер.
  • copy — указывает, нужно ли копировать элемент вместо перемещения.
  • revertOnSpill — возвращает элемент на исходное место, если он был брошен вне контейнера.
const drake = dragula(containers, {
  moves: (el, source, handle, sibling) => handle.classList.contains('handle'),
  accepts: (el, target, source, sibling) => !target.classList.contains('no-drop'),
  copy: false,
  revertOnSpill: true
});

Работа с событиями

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

  • drag — начинается перетаскивание элемента.
  • dragend — завершение перетаскивания, элемент возвращается на место или остается в новом контейнере.
  • drop — элемент успешно брошен в контейнер.
  • over / out — курсор с элементом входит или покидает контейнер.
  • cancel — отмена перетаскивания.

Пример использования событий:

drake.on('drag', (el) => {
  el.style.opacity = '0.5';
});

drake.on('drop', (el, target, source, sibling) => {
  el.style.opacity = '';
  console.log(`Элемент ${el.textContent} перемещен в контейнер ${target.id}`);
});

drake.on('cancel', (el, container, source) => {
  el.style.opacity = '';
});

Копирование и клонирование элементов

Dragula позволяет реализовать поведение, при котором элемент копируется, а не перемещается. Это удобно для интерфейсов типа «drag-to-create».

const drake = dragula([document.getElementById('source'), document.getElementById('destination')], {
  copy: true
});

При необходимости можно контролировать, какие элементы копируются:

const drake = dragula([sourceContainer, destinationContainer], {
  copy: (el, source) => el.classList.contains('copyable')
});

Ограничение перетаскивания и допустимых контейнеров

Функция accepts позволяет задать правила для каждого элемента и контейнера:

const drake = dragula([left, right], {
  accepts: (el, target) => target.id !== 'left' || el.classList.contains('movable')
});

В этом примере элементы, не имеющие класса movable, нельзя переместить обратно в контейнер с id left.


Программное управление элементами

Dragula предоставляет методы для управления элементами без взаимодействия пользователя:

  • drake.remove(el) — удаляет элемент из контейнера.
  • drake.cancel(true) — отменяет текущее перетаскивание.
  • drake.containers.push(container) — добавляет новый контейнер для работы drag-and-drop.
  • drake.destroy() — полностью удаляет Dragula-инстанс, очищает события.

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

const newContainer = document.getElementById('new');
drake.containers.push(newContainer);

Стилизация и визуальные эффекты

Для удобства восприятия пользователем процесса перетаскивания Dragula использует CSS-классы:

  • gu-transit — элемент во время перетаскивания.
  • gu-mirror — копия элемента, которая следует за курсором.
  • gu-hide — скрывает оригинальный элемент при копировании.
  • gu-unselectable — запрещает выделение текста во время перетаскивания.
.gu-transit {
  opacity: 0.3;
  border: 1px dashed #aaa;
}

.gu-mirror {
  position: fixed;
  z-index: 9999;
  opacity: 0.8;
}

Интеграция с динамическим контентом

При работе с динамическими элементами необходимо убедиться, что Dragula «видит» новые контейнеры. Для этого после добавления новых элементов или контейнеров следует обновить список:

const dynamicContainer = document.createElement('div');
dynamicContainer.id = 'dynamic';
document.body.appendChild(dynamicContainer);
drake.containers.push(dynamicContainer);

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


Управление жизненным циклом элементов

Dragula позволяет полностью контролировать перемещение элементов на протяжении всего жизненного цикла:

  1. Инициализация — выбор контейнеров, настройка правил перетаскивания.
  2. Перетаскивание — управление стилями, курсором и визуальными эффектами.
  3. Бросок — обработка drop и cancel, выполнение бизнес-логики.
  4. Удаление/копирование — программное управление элементами, создание клонов.
  5. Очистка — уничтожение инстанса Dragula через destroy() для освобождения ресурсов.

Правильное использование этих этапов обеспечивает стабильную работу drag-and-drop интерфейсов и предотвращает появление конфликтов при динамических изменениях DOM.


Хотите, я могу сделать отдельный блок с реальными сценариями применения Dragula для сложных интерфейсов, где покажу практическое управление жизненным циклом элементов с массивами данных и AJAX-запросами?