Dragula — это JavaScript-библиотека, упрощающая реализацию функциональности перетаскивания элементов между контейнерами. Она строится поверх Native HTML5 Drag and Drop API, но снимает большую часть сложности, связанной с событиями, манипуляцией классов и вычислением координат.
Библиотека обеспечивает следующие ключевые возможности:
dragstart,
dragover, drop.Для начала работы необходимо подключить библиотеку и определить контейнеры:
import dragula from 'dragula';
const containers = [document.getElementById('left'), document.getElementById('right')];
const drake = dragula(containers);
Пояснение:
containers — массив DOM-элементов, между которыми
разрешено перемещать элементы.drake — объект Dragula, через который управляются
события и настройки.Dragula предоставляет объект настроек при инициализации. Основные свойства:
moves — функция, определяющая, можно ли
перетаскивать элемент. Возвращает true или
false.
moves: function (el, source, handle, sibling) {
return handle.classList.contains('handle');
}accepts — функция, определяющая, можно ли сбросить
элемент в конкретный контейнер.
accepts: function (el, target, source, sibling) {
return !target.classList.contains('locked');
}copy — указывает, будет ли элемент копироваться при
перетаскивании (true) или перемещаться
(false).
Dragula предоставляет богатый набор событий для управления жизненным циклом перетаскивания:
drag — срабатывает при начале перетаскивания.
drake.on('drag', function(el) {
el.style.opacity = '0.5';
});drop — срабатывает при успешном перемещении элемента
в контейнер.
drake.on('drop', function(el, target, source, sibling) {
el.style.opacity = '';
});over и out — реагируют на вход и выход
элемента в контейнер.
cancel — срабатывает при отмене перетаскивания,
например, если элемент был отпущен вне контейнера.
Dragula автоматически добавляет CSS-классы:
.gu-mirror — создается копия перетаскиваемого элемента,
которая следует за курсором..gu-hide — скрывает оригинальный элемент при
перемещении..gu-unselectable — предотвращает выделение текста во
время перетаскивания.Эти классы можно переопределять в CSS для реализации уникального визуального поведения.
Dragula позволяет работать с множеством контейнеров одновременно. При инициализации достаточно передать массив:
const drake = dragula([container1, container2, container3]);
Можно контролировать, в какие контейнеры разрешено перемещать
элементы, через функцию accepts.
Для реализации функционала «перетащить и скопировать» используется
опция copy:
const drake = dragula(containers, { copy: true });
Если требуется копировать элементы только из конкретного контейнера:
copy: function(el, source) {
return source.id === 'left';
}
Функция moves позволяет ограничивать перетаскивание:
moves: function(el, source, handle, sibling) {
return !el.classList.contains('locked');
}
Это особенно полезно, когда некоторые элементы являются статичными или служат заголовками.
Dragula не изменяет DOM, кроме перемещения элементов, поэтому данные
формы и атрибуты сохраняются. Для синхронизации с состоянием приложения
можно использовать событие drop:
drake.on('drop', function(el, target, source, sibling) {
const updatedList = Array.from(target.children).map(item => item.dataset.id);
console.log('Новая последовательность элементов:', updatedList);
});
Dragula допускает интеграцию с асинхронными действиями. Например,
можно при drop отправлять данные на сервер и отменять
перемещение при ошибке:
drake.on('drop', async function(el, target, source, sibling) {
try {
await sendUpdateToServer(target.id, el.dataset.id);
} catch {
drake.cancel(true);
}
});
Для больших списков рекомендуется:
moves для ограничения перетаскиваемых
элементов.drag и
over.drop.Dragula использует нативный HTML5 Drag and Drop для определения
позиции курсора и контейнера, но не полагается на встроенные
DataTransfer-данные. Это позволяет избежать проблем с
совместимостью между браузерами и обеспечивает более плавное
перетаскивание.
Dragula сочетает простоту использования с гибкостью настройки, позволяя создавать сложные интерфейсы с перетаскиваемыми элементами, минимизируя прямую работу с низкоуровневыми событиями Native HTML5 Drag and Drop API.