Dragula — это легковесная библиотека на JavaScript, предназначенная для реализации перетаскивания элементов между контейнерами с минимальными настройками. Она ориентирована на упрощение интерфейсов с drag-and-drop, исключая сложные зависимости и предоставляя чистый API.
Библиотека работает с любыми DOM-элементами, создавая drag-and-drop контейнеры, внутри которых можно перемещать элементы. Основная концепция Dragula строится на следующих компонентах:
drag, drop, over,
out, cancel, cloned и
другие.Подключение 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
Создание Dragula-инстанса выглядит так:
const drake = dragula([document.querySelector('#left'), document.querySelector('#right')]);
Dragula поддерживает набор настроек, влияющих на поведение перетаскивания:
true, если элемент можно перетаскивать.true, элемент копируется
при перетаскивании, а не перемещается.Пример использования настроек:
const drake = dragula([leftContainer, rightContainer], {
moves: (el, source, handle) => handle.classList.contains('handle'),
accepts: (el, target) => target.id !== 'restricted',
copy: false,
revertOnSpill: true
});
Dragula предоставляет события, которые можно подписывать через метод
.on:
Пример подписки:
drake.on('drag', (el, source) => {
console.log('Начало перетаскивания', el);
});
drake.on('drop', (el, target, source, sibling) => {
console.log('Элемент перемещен', el, 'в', target);
});
При работе с drag-and-drop часто возникает ситуация, когда события вызываются слишком часто, особенно при динамическом изменении DOM или анимациях. Здесь на помощь приходят throttling и debouncing, которые помогают контролировать частоту вызова функций.
Throttling ограничивает количество вызовов функции
за определённый период времени. Он полезен, когда события происходят
постоянно (например, dragover) и нужно обрабатывать их не
чаще раза в N миллисекунд.
Пример использования с Dragula:
function throttle(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
const handleDragOver = throttle((el, container) => {
console.log('Обработка dragover с throttling', el);
}, 200);
drake.on('over', handleDragOver);
В этом примере обработка события over выполняется не
чаще одного раза в 200 мс, что снижает нагрузку на DOM и улучшает
производительность интерфейса.
Debouncing задерживает вызов функции до тех пор, пока событие не прекратится на определённый интервал времени. Он полезен для действий, которые должны выполняться только после завершения серии быстрых событий, например при отпускании элемента после drag-and-drop.
Пример debounce:
function debounce(func, delay) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), delay);
};
}
const handleDropDebounced = debounce((el, target) => {
console.log('Элемент отпущен после дебаунса', el, target);
}, 300);
drake.on('drop', handleDropDebounced);
Использование дебаунса гарантирует, что логика обработки срабатывает один раз после завершения всех быстрых перетаскиваний.
drag, over,
out.drop, когда
нужно выполнить тяжелую операцию только после завершения
перемещения._.throttle и
_.debounce).При большом количестве draggable-элементов или при работе на слабых устройствах важно:
Dragula легко интегрируется с современными фреймворками, такими как React, Vue и Angular. Основная рекомендация — управлять состоянием через фреймворк, а Dragula использовать для визуального перетаскивания, применяя throttling и debouncing для синхронизации состояния.
Хотите, я могу создать отдельный раздел с реальными примерами комплексного интерфейса с Dragula и debounce/throttle, где элементы перетаскиваются между множеством контейнеров с сохранением состояния?