Dragula — это легковесная библиотека для
перетаскивания элементов (drag-and-drop) на веб-страницах. Она работает
с чистым JavaScript и минимально зависит от внешних библиотек, что
делает её удобной для интеграции в любые проекты. Центральный объект
библиотеки создаётся вызовом функции
dragula(containers, options), где containers —
массив контейнеров, в которых будут перемещаться элементы, а
options — объект конфигурации, позволяющий точно управлять
поведением перетаскивания.
Контейнеры определяют области, между которыми допускается перемещение элементов. В Dragula контейнеры могут быть указаны как:
const containers = [document.getElementById('left'), document.getElementById('right')];
dragula(containers);
Элементы могут перемещаться между контейнерами или внутри одного контейнера в зависимости от настроек. Контейнеры динамически расширяются: новые элементы, добавленные в DOM, автоматически становятся частью механизма перетаскивания, если они находятся в указанных контейнерах.
movesФункция, определяющая, можно ли начать перетаскивание конкретного элемента. Сигнатура:
function moves(el, source, handle, sibling) { return true|false; }
el — сам элемент, который пытаются перетащить.source — контейнер, из которого происходит
перетаскивание.handle — элемент, по которому пользователь начал
перетаскивать.sibling — элемент, перед которым может быть вставлен
el.Пример ограничения перетаскивания только по определённой области элемента:
moves: function (el, source, handle) {
return handle.classList.contains('handle');
}
acceptsФункция, определяющая, можно ли вставить элемент в определённый контейнер и перед конкретным соседом:
function accepts(el, target, source, sibling) { return true|false; }
el — элемент, который перемещается.target — контейнер, куда пытаются переместить.source — исходный контейнер.sibling — элемент, перед которым будет вставлен
el.Пример: разрешить перемещение только между контейнерами с классом
droppable:
accepts: function(el, target) {
return target.classList.contains('droppable');
}
copyПозволяет создавать копию элемента вместо перемещения. Может быть булевым значением или функцией:
copy: true
или
copy: function(el, source) { return el.classList.contains('cloneable'); }
При использовании copy исходный элемент остаётся на
месте, а в контейнер вставляется его клон.
copySortSourceПозволяет сортировать элементы внутри контейнера, если включено копирование. Булевое значение:
copySortSource: false
Если true, можно изменять порядок элементов даже в
исходном контейнере при копировании.
revertOnSpillОпределяет, что происходит с элементом, если его отпустили вне контейнера:
revertOnSpill: true
При значении true элемент возвращается на исходное
место. При false элемент остаётся в DOM там, где его
отпустили.
removeOnSpillАльтернатива revertOnSpill. Удаляет элемент из DOM, если
его отпустили вне контейнера:
removeOnSpill: true
Используется для интерфейсов, где элемент должен исчезать при «выбрасывании» вне допустимой зоны.
directionОпределяет направление сортировки внутри контейнера:
'vertical' или 'horizontal':
direction: 'vertical'
Это влияет на вычисление позиции вставки элемента относительно соседей.
ignoreInputTextSelectionЕсли установлено в true, текстовые поля и textarea не
блокируют перетаскивание:
ignoreInputTextSelection: true
Эта опция предотвращает случайные срабатывания drag при выделении текста внутри инпутов.
invalidФункция, которая запрещает перетаскивание определённых элементов:
invalid: function(el, handle) { return el.classList.contains('no-drag'); }
Если функция возвращает true, перетаскивание не
инициируется.
directionLockОграничивает направление перетаскивания, особенно полезно на сенсорных устройствах. Обычно используется вместе с кастомными обработчиками событий.
Dragula предоставляет богатый набор событий для управления логикой перетаскивания:
drag — элемент начал перетаскиваться.drop — элемент успешно вставлен.over — элемент наведён на контейнер.out — элемент покинул контейнер.cancel — перетаскивание отменено.remove — элемент удалён из DOM.Пример подписки на события:
const drake = dragula(containers);
drake.on('drop', function(el, target, source, sibling) {
console.log('Элемент перемещён', el, 'в', target);
});
drake.on('remove', function(el) {
console.log('Элемент удалён', el);
});
Dragula автоматически поддерживает новые элементы в контейнерах, но
для динамически созданных контейнеров требуется добавить их через метод
drake.containers.push(newContainer). Это позволяет
расширять зоны перетаскивания без пересоздания Dragula-инстанса.
Для корректной работы Dragula важны следующие CSS-классы:
.gu-mirror — копия элемента, которая тянется за
курсором..gu-hide — скрывает исходный элемент при
перетаскивании..gu-transit — применяется к элементу на время
перемещения..gu-unselectable — предотвращает выделение текста при
перетаскивании.Использование этих классов позволяет создавать плавные визуальные эффекты и полностью контролировать внешний вид элементов во время drag-and-drop.
Dragula легко интегрируется с фреймворками вроде React, Vue и
Angular. Основная рекомендация — управлять состоянием контейнеров через
обычный DOM, чтобы Dragula корректно отслеживала элементы. Для
реактивных фреймворков часто используют эффект useEffect
или аналогичный жизненный цикл для инициализации и уничтожения
drag-сессий.
moves и accepts для
фильтрации элементов, чтобы сокращать вычисления.Эти возможности делают Dragula мощным инструментом для организации гибких интерфейсов с перетаскиванием, позволяя детально настраивать логику перемещения, ограничения и визуальные эффекты для элементов.