drop - размещение элемента

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

Для использования Dragula достаточно подключить библиотеку через CDN или npm-пакет:

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

Или через npm:

npm install dragula

Импорт в модульном окружении:

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

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

Контейнеры — это элементы DOM, между которыми можно перемещать элементы. Dragula принимает массив контейнеров при инициализации:

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

const drake = dragula(containers);

Ключевой момент: все элементы, которые должны быть перетаскиваемыми, должны находиться внутри указанных контейнеров. Dragula автоматически добавляет обработчики событий для mousedown, mousemove и mouseup для этих элементов.


Основные события Dragula

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

  • drag: возникает в момент начала перетаскивания. Позволяет менять стиль перетаскиваемого элемента.
  • drop: возникает при отпускании элемента. На этом событии можно выполнить логику обновления данных.
  • over и out: фиксируют наведение перетаскиваемого элемента на контейнер и уход из него.
  • cancel: вызывается, если перетаскивание было отменено.
  • cloned: используется при создании клона элемента вместо перемещения оригинала.

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

drake.on('drop', (el, target, source, sibling) => {
  console.log('Элемент', el, 'перемещён в', target);
});
  • el — перемещённый элемент.
  • target — контейнер, в который элемент был перемещён.
  • source — исходный контейнер.
  • sibling — элемент, перед которым вставлен перемещённый, или null, если в конец.

Настройки Dragula

Dragula позволяет тонко настраивать поведение перетаскивания через объект конфигурации при инициализации или метод options().

Основные параметры:

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

Работа с клонами элементов

Иногда требуется не перемещать элемент, а создавать его копию при переносе. Для этого используется опция copy:

const drake = dragula(containers, { copy: true });

Событие cloned позволяет получить ссылку на создаваемый клон:

drake.on('cloned', (clone, original, type) => {
  console.log('Создан клон элемента', clone);
});
  • clone — копия элемента.
  • original — исходный элемент.
  • type'mirror' или 'copy', указывающий тип клонирования.

Ограничение зон перетаскивания

Dragula позволяет ограничить перемещение элементов с помощью функций moves и accepts. Например, можно разрешить перемещение только по определённым контейнерам:

const drake = dragula(containers, {
  accepts: (el, target) => target.id !== 'restrictedContainer'
});

Также можно ограничить перенос по конкретным зонам «хэндлов»:

moves: (el, source, handle) => handle.classList.contains('draggable-handle')

Визуальные эффекты

Dragula автоматически добавляет класс gu-mirror для элемента-перетаскивателя, который следует за курсором. Для изменения внешнего вида можно использовать CSS:

.gu-mirror {
  opacity: 0.8;
  background-color: #f0f0f0;
  border: 2px dashed #aaa;
}

Другие полезные классы:

  • .gu-hide — скрывает элемент на исходной позиции.
  • .gu-unselectable — предотвращает выделение текста при перетаскивании.
  • .gu-transit — используется для анимации перехода элемента.

Управление перетаскиванием программно

Методы Dragula позволяют запускать или останавливать перетаскивание через код:

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

Пример сложного использования

Организация канбан-доски с Dragula:

const containers = Array.from(document.querySelectorAll('.kanban-column'));

const drake = dragula(containers, {
  moves: (el, source, handle) => handle.classList.contains('kanban-handle'),
  accepts: (el, target) => target.classList.contains('kanban-column'),
  revertOnSpill: true
});

drake.on('drop', (el, target, source, sibling) => {
  const itemId = el.dataset.id;
  const columnId = target.dataset.column;
  console.log(`Элемент ${itemId} перемещён в колонку ${columnId}`);
  // Здесь может быть обновление состояния на сервере через API
});

Такой подход позволяет создавать гибкие интерфейсы перетаскивания с контролем доступа, визуальными эффектами и интеграцией с бизнес-логикой.


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