Переход с других библиотек

Dragula — это лёгкая библиотека для реализации drag-and-drop интерфейсов в браузере, написанная на чистом JavaScript. Она отличается простотой интеграции, минимальными зависимостями и удобной системой событий. Основная цель Dragula — позволить перемещать элементы между контейнерами и внутри одного контейнера без сложной настройки.

Главное преимущество Dragula перед более тяжёлыми библиотеками типа jQuery UI или SortableJS — это автоматическое управление позициями элементов, отсутствие необходимости в явной конфигурации и поддержка touch-событий для мобильных устройств.

Подключение Dragula

Dragula можно использовать через CDN или через пакетный менеджер npm/yarn. Пример подключения через CDN:

<link rel="stylesheet" href="https://unpkg.com/dragula/dist/dragula.min.css">
<script src="https://unpkg.com/dragula/dist/dragula.min.js"></script>

Для npm:

npm install dragula

И подключение в проект:

import dragula from 'dragula';
import 'dragula/dist/dragula.css';

Инициализация и базовое использование

Инициализация Dragula происходит через вызов функции dragula() с передачей массива контейнеров:

const containers = [
  document.getElementById('container1'),
  document.getElementById('container2')
];

const drake = dragula(containers);

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

Настройка поведения

Dragula предоставляет ряд опций для настройки:

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

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

Dragula генерирует множество событий, на которые можно подписываться:

  • drag — срабатывает при начале перетаскивания.
  • drop — срабатывает после того, как элемент был помещён в контейнер.
  • over / out — при наведении на контейнер и уходе с него.
  • cancel — при отмене перетаскивания.
  • cloned — когда элемент клонируется (при опции copy).

Пример подписки на событие drop:

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

Интеграция с существующими библиотеками

При переходе с других drag-and-drop библиотек Dragula позволяет значительно уменьшить количество кода, поскольку многие стандартные операции выполняются автоматически. Например, для SortableJS приходилось вручную управлять позициями элементов, в Dragula это делается без дополнительного кода.

При интеграции стоит обратить внимание на следующие моменты:

  1. Структура контейнеров и элементов Dragula работает с DOM-элементами напрямую, поэтому все элементы должны быть реальными HTML-узлами. Если предыдущая библиотека использовала виртуальный DOM или абстракцию, потребуется адаптация.

  2. Стили и визуальные эффекты Dragula добавляет классы gu-mirror, gu-hide, gu-transit, которые позволяют стилизовать элемент во время перетаскивания. Это отличается от систем, где визуальные эффекты создаются через JS-анимацию.

  3. Обработка touch-событий В отличие от некоторых библиотек, Dragula изначально поддерживает сенсорные экраны без дополнительных плагинов.

  4. Минимизация событийного кода Если предыдущая библиотека требовала множество слушателей событий для drag-start, drag-end, drag-over, drop, то Dragula объединяет большинство этих функций через удобные колбэки и глобальные события.

Расширенные возможности

Dragula можно расширять с помощью кастомных опций:

  • Сортировка внутри контейнера: можно отслеживать событие drop и реорганизовывать элементы в зависимости от их позиции.
  • Динамическое добавление контейнеров: drake.containers.push(newContainer) позволяет добавлять новые контейнеры без повторной инициализации.
  • Удаление элементов при броске вне контейнера: комбинация revertOnSpill: false и события spill позволяет автоматически удалять элементы.

Пример комплексной интеграции

const drake = dragula([], {
  copy: false,
  revertOnSpill: true,
  moves: (el, source, handle) => handle.classList.contains('drag-handle')
});

const allContainers = document.querySelectorAll('.drag-container');
allContainers.forEach(container => drake.containers.push(container));

drake.on('drop', (el, target, source) => {
  el.style.backgroundColor = '#f0f0f0';
});

Этот подход позволяет гибко управлять поведением элементов, минимизируя лишний код и конфликт с предыдущими библиотеками. Dragula хорошо подходит для приложений, где важна скорость интеграции и простота поддержки интерфейса drag-and-drop, особенно при переходе с более сложных или громоздких решений.