Dragula — это библиотека для реализации перетаскивания элементов (drag-and-drop) в веб-приложениях на JavaScript. Она ориентирована на простоту использования и минимальную настройку, сохраняя при этом гибкость для сложных сценариев. В основе Dragula лежит принцип drag-and-drop без состояния: библиотека не управляет данными приложения, а только DOM, что позволяет интегрировать её с любыми фреймворками, включая React, Angular и Vue.
Для работы с Dragula доступны два основных способа подключения: через npm и через CDN.
Через npm:
npm install dragula
Подключение в проекте:
import dragula from 'dragula';
import 'dragula/dist/dragula.css';
CSS-файл Dragula содержит базовые стили для визуального выделения перетаскиваемого элемента и контейнеров. Без него взаимодействие будет работать, но элементы не будут визуально подсвечиваться во время перетаскивания.
Основной принцип Dragula заключается в создании коллекции контейнеров, внутри которых можно перетаскивать элементы. Контейнер — это любой DOM-элемент, содержащий дочерние элементы.
const containers = [
document.getElementById('left-panel'),
document.getElementById('right-panel')
];
const drake = dragula(containers);
После инициализации drake предоставляет набор событий и
методов для управления перетаскиванием. Контейнеры могут быть любыми
HTML-элементами, включая <div>,
<ul> и <ol>.
Dragula поддерживает несколько опций, позволяющих гибко контролировать поведение перетаскивания.
Основные опции:
moves(el, source, handle, sibling): функция,
возвращающая true, если элемент el может быть
перетащен.accepts(el, target, source, sibling): функция,
определяющая, можно ли вставить элемент el в контейнер
target.copy: логическое значение или функция, указывающая,
следует ли копировать элемент вместо перемещения.revertOnSpill: если true, элемент
возвращается на исходную позицию, если сброшен вне контейнеров.removeOnSpill: удаляет элемент, если сброшен вне
контейнера.Пример использования опций:
const drake = dragula(containers, {
moves: (el, source, handle) => handle.classList.contains('handle'),
accepts: (el, target) => target.id !== 'left-panel',
copy: false,
revertOnSpill: true
});
Dragula предоставляет богатый набор событий, которые позволяют реагировать на действия пользователя:
drag: элемент начал перетаскиваться.dragend: элемент завершил перетаскивание.drop: элемент успешно сброшен в контейнер.over: элемент находится над контейнером.out: элемент покинул контейнер.cancel: перетаскивание было отменено.cloned: создается копия элемента при включенной опции
copy.Пример подписки на события:
drake.on('drag', el => {
console.log('Начало перетаскивания', el);
});
drake.on('drop', (el, target, source, sibling) => {
console.log('Элемент перемещен', el, 'в контейнер', target.id);
});
Dragula не управляет состоянием React напрямую, поэтому необходимо
синхронизировать DOM с состоянием компонентов. Стандартный подход —
обновлять состояние компонентов после события drop.
Пример компонента React:
import React, { useEffect, useRef, useState } from 'react';
import dragula from 'dragula';
import 'dragula/dist/dragula.css';
function DragList() {
const [items, setItems] = useState(['Элемент 1', 'Элемент 2', 'Элемент 3']);
const containerRef = useRef(null);
useEffect(() => {
const drake = dragula([containerRef.current]);
drake.on('drop', (el, target, source, sibling) => {
const newOrder = Array.from(containerRef.current.children).map(child => child.textContent);
setItems(newOrder);
});
return () => drake.destroy();
}, []);
return (
<div ref={containerRef}>
{items.map((item, index) => (
<div key={index}>{item}</div>
))}
</div>
);
}
В этом примере Dragula управляет только визуальной частью перетаскивания, а состояние React обновляется на основе текущего порядка элементов DOM.
Клонирование элементов: с помощью опции
copy можно создавать копии элементов вместо
перемещения.
Динамические контейнеры: можно добавлять новые
контейнеры после инициализации Dragula с помощью метода
drake.containers.push(newContainer).
Анимация и стили: можно задавать собственные
CSS-классы для перетаскиваемых элементов с помощью
dragula.css или кастомных стилей, чтобы улучшить визуальный
отклик при перемещении.
Поддержка touch: Dragula работает на мобильных устройствах без дополнительных библиотек, что делает её удобной для адаптивных интерфейсов.
drop, а не во время перетаскивания.moves и accepts для
ограничения зон перетаскивания и контроля логики приложения.Dragula сочетает простоту использования с высокой гибкостью, позволяя создавать как простые списки с перетаскиванием, так и сложные интерфейсы с множественными контейнерами и динамическими элементами.