Dragula — это легковесная библиотека для перетаскивания элементов между контейнерами. Важная особенность Dragula — возможность создания кастомных обработчиков событий, что позволяет полностью контролировать поведение перетаскивания, включая ограничения на перенос, визуальные эффекты и динамическое управление элементами.
Для инициализации Dragula используется функция
dragula(containers, options), где containers —
массив DOM-элементов, а options — объект с параметрами.
Основные опции, связанные с кастомизацией:
moves — функция, определяющая, можно ли перемещать элемент.
moves: function (el, source, handle, sibling) {
return handle.classList.contains('handle');
}
В этом примере элемент можно перемещать только за специфический
дочерний узел с классом handle.
accepts — функция, контролирующая, разрешён ли перенос элемента в конкретный контейнер.
accepts: function (el, target, source, sibling) {
return !target.classList.contains('no-drop');
}
Здесь запрещён перенос в контейнер с классом
no-drop.
invalid — функция, определяющая элементы, которые не могут быть перетащены.
invalid: function (el, handle) {
return el.classList.contains('fixed');
}copy — позволяет указать, будет ли элемент копироваться или перемещаться. Может быть функцией для динамического контроля.
copy: function(el, source) {
return source.id === 'source-list';
}Dragula предоставляет богатый набор событий, на которые можно навесить кастомные функции:
drag — срабатывает при начале перетаскивания. Позволяет изменять стиль элемента:
drake.on('drag', function(el) {
el.style.opacity = '0.5';
});dragend — вызывается при завершении перетаскивания, полезно для очистки временных стилей:
drake.on('dragend', function(el) {
el.style.opacity = '';
});drop — срабатывает при успешной установке элемента в новый контейнер. Здесь можно реализовать логику сортировки или синхронизации данных:
drake.on('drop', function(el, target, source, sibling) {
console.log(`Элемент ${el.textContent} перемещён в ${target.id}`);
});over / out — позволяют реализовать визуальные подсказки при наведении на контейнеры:
drake.on('over', function(el, container) {
container.classList.add('highlight');
});
drake.on('out', function(el, container) {
container.classList.remove('highlight');
});cancel — можно использовать для отмены переноса на определённых условиях.
shadow — предоставляет возможность работать с элементом-заполнителем, который Dragula использует во время перетаскивания.
Dragula позволяет не только перемещать элементы, но и динамически управлять ими в процессе drag&drop:
Создание элементов “на лету”: можно клонировать
элемент и помещать его в другой контейнер при событии
drag:
drake.on('drag', function(el) {
const clone = el.cloneNode(true);
clone.classList.add('clone');
document.querySelector('#clone-container').appendChild(clone);
});Изменение порядка: можно программно перемещать
элементы, взаимодействуя с sibling в событии
drop:
drake.on('drop', function(el, target, source, sibling) {
if(sibling) {
target.insertBefore(el, sibling);
} else {
target.appendChild(el);
}
});Ограничения на перенос по типам элементов:
комбинируя moves и accepts, можно реализовать
строгие правила, например, запрещать перемещение заголовков между
списками или разрешать только определённые категории элементов.
Можно создавать и удалять обработчики Dragula в зависимости от состояния интерфейса:
Отключение Dragula на контейнере:
drake.remove(); // полностью удаляет слушатели и контейнерыВременное блокирование перемещения:
drake.options.moves = function() { return false; };Повторная активация с новыми опциями:
drake.options.moves = function(el, source, handle) {
return handle.classList.contains('draggable');
};Использование CSS-классов для визуальной обратной
связи: Создание динамических классов dragging,
over, invalid для плавного
интерфейса.
Асинхронная проверка: функции
accepts или moves могут использовать
асинхронные данные (например, с сервера) для решения, можно ли
перемещать элемент. В этом случае часто применяется временная блокировка
визуального перетаскивания до получения ответа.
Комбинирование с другими библиотеками: Dragula может интегрироваться с фреймворками типа React или Vue через кастомные события и состояние компонентов.
drag и dragend для управления
визуальными эффектами и предотвращения мерцаний при перемещении.accepts и moves, чтобы
избежать конфликтов при сложных правилах перетаскивания.