Dragula — это легковесная библиотека для реализации drag-and-drop интерфейсов на JavaScript без необходимости подключения больших фреймворков. Она предоставляет простое API для перетаскивания элементов между контейнерами с поддержкой визуальных эффектов и коллизий. Установка производится через npm или CDN:
npm install dragula
или подключение через <script>:
<script src="https://unpkg.com/dragula/dist/dragula.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/dragula/dist/dragula.min.css">
После подключения библиотека готова к использованию на любых DOM-элементах.
Создание экземпляра Dragula осуществляется вызовом функции
dragula() с массивом контейнеров:
const containers = [document.getElementById('left'), document.getElementById('right')];
const drake = dragula(containers);
Ключевые методы:
drake.on(event, callback) — подписка на события:
drag, drop, over,
out, cancel.drake.destroy() — полное удаление всех слушателей и
очистка состояния.drake.containers — массив текущих контейнеров для
перетаскивания.Dragula поддерживает конфигурацию через объект опций:
const drake = dragula(containers, {
moves: (el, source, handle, sibling) => handle.classList.contains('handle'),
accepts: (el, target, source, sibling) => !target.classList.contains('forbidden'),
copy: true,
revertOnSpill: true,
});
Основные опции:
true элементы
копируются, вместо перемещения.Dragula генерирует набор событий, на которых можно строить интерактивное поведение:
drag(el, source) — элемент начал перетаскиваться.drop(el, target, source, sibling) — элемент отпущен в
контейнер.over(el, container, source) — элемент наведен на
контейнер.out(el, container, source) — элемент покинул
контейнер.cancel(el, container, source) — перетаскивание было
отменено.Пример использования:
drake.on('drop', (el, target, source, sibling) => {
console.log(`Элемент ${el.textContent} перемещен из ${source.id} в ${target.id}`);
});
Dragula использует стандартные события drag и
drop браузера и не требует дополнительных полифиллов для
современных версий Chrome, Firefox, Edge или Safari. Для IE11 и
ниже могут возникать проблемы с:
classList на SVG-элементах.CustomEvent.Array.prototype.find, forEach на
NodeList.Полифиллы для Dragula:
<script src="https://cdn.jsdelivr.net/npm/classlist-polyfill@1.2.0/index.min.js"></script>
(function () {
if ( typeof window.CustomEvent === "function" ) return false;
function CustomEvent ( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: null };
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
}
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
})();
if (!Array.prototype.find) {
Array.prototype.find = function(predicate) {
if (this == null) throw new TypeError('Array.prototype.find called on null or undefined');
if (typeof predicate !== 'function') throw new TypeError('predicate must be a function');
var list = Object(this);
var length = list.length >>> 0;
var thisArg = arguments[1];
for (var i = 0; i < length; i++) {
var value = list[i];
if (predicate.call(thisArg, value, i, list)) return value;
}
return undefined;
};
}
if (window.NodeList && !NodeList.prototype.forEach) {
NodeList.prototype.forEach = Array.prototype.forEach;
}
Dragula добавляет класс gu-transit элементу во время
перемещения. Остальные классы:
gu-mirror — копия элемента, следящая за курсором.gu-hide — скрывает исходный элемент, если включен режим
копирования.gu-unselectable — предотвращает выделение текста.Стилизация может быть выполнена через CSS:
.gu-mirror {
background: rgba(0, 150, 255, 0.2);
border: 2px dashed #0096ff;
box-shadow: 0 5px 15px rgba(0,0,0,0.3);
}
.gu-transit {
opacity: 0.5;
}
Dragula легко интегрируется с React, Vue и Angular, так как работает напрямую с DOM. Основные рекомендации:
useEffect для
инициализации и удаления экземпляра Dragula.mounted() и
уничтожать в beforeDestroy().ngAfterViewInit и очистка в ngOnDestroy.Dragula подходит для:
Благодаря малому размеру, простому API и минимальным зависимостям, библиотека позволяет создавать интерактивные интерфейсы с минимальной нагрузкой на проект.