Dragula — это легковесная библиотека для реализации drag-and-drop функционала в веб-приложениях на JavaScript. Основной её принцип заключается в управлении перемещениями элементов между контейнерами с минимальными усилиями, предоставляя набор событий и опций для тонкой настройки поведения.
Перемещение в Dragula осуществляется за счёт создания drake — объекта, который управляет всеми аспектами перетаскивания. Создание drake выглядит следующим образом:
const drake = dragula([container1, container2]);
В этот момент Dragula отслеживает действия пользователя, начиная с нажатия мыши на элемент и заканчивая его отпусканием в целевой контейнер.
Валидация перемещений — ключевой инструмент для контроля над тем,
какие элементы могут быть перемещены и куда. В Dragula это реализуется
через опцию moves и ряд вспомогательных функций:
movesmoves — это функция, вызываемая каждый раз, когда
начинается попытка перетаскивания. Она получает три аргумента:
el — элемент, который пытаются перетащить;source — контейнер, из которого происходит
перемещение;handle — элемент, по которому был выполнен захват
мышью.Пример функции moves, запрещающей перемещение элементов
с классом locked:
const drake = dragula([container1, container2], {
moves: (el, source, handle) => {
return !el.classList.contains('locked');
}
});
Здесь ключевой момент: возвращение true разрешает
перемещение, false — запрещает.
acceptsaccepts отвечает за валидацию целевых контейнеров. Она
принимает четыре аргумента:
el — элемент, который перетаскивается;target — контейнер, в который предполагается поместить
элемент;source — контейнер, из которого элемент берётся;sibling — элемент, перед которым будет вставлен
перетаскиваемый элемент, либо null, если элемент
добавляется в конец.Пример ограничения перемещения в определённый контейнер:
const drake = dragula([container1, container2], {
accepts: (el, target, source, sibling) => {
return target.id !== 'restricted-container';
}
});
Таким образом, элемент может быть перетащен только в контейнеры, не
помеченные как restricted-container.
Dragula предоставляет ряд событий, которые помогают контролировать процесс перемещения:
drag — срабатывает при начале перетаскивания;drop — срабатывает при успешном размещении
элемента;over и out — при наведении и уходе
элемента над контейнером;cancel — при отмене перемещения.Пример валидации через событие drop:
drake.on('drop', (el, target, source, sibling) => {
if (target.classList.contains('no-drop')) {
source.appendChild(el);
}
});
Здесь при попытке сброса элемента в контейнер с классом
no-drop элемент возвращается в исходный контейнер.
Dragula позволяет изменять правила перемещения во время работы
приложения. Для этого можно переназначать функции moves и
accepts или использовать событие drag для
динамической блокировки элементов.
Пример блокировки всех элементов при включении режима редактирования:
let editMode = false;
const drake = dragula([container1, container2], {
moves: (el) => {
return editMode;
}
});
// Включение режима редактирования
editMode = true;
Для сложных интерфейсов важно учитывать дополнительные условия:
Пример с контролем позиции:
const drake = dragula([container1, container2], {
accepts: (el, target, source, sibling) => {
if (sibling && sibling.classList.contains('protected')) {
return false;
}
return true;
}
});
Это предотвращает вставку элемента перед защищёнными элементами.
Для полного контроля перемещений часто требуется комбинация опций
moves и accepts с дополнительными проверками
через события. Такой подход обеспечивает:
Правильная организация этих функций позволяет создавать интуитивные и безопасные drag-and-drop интерфейсы, полностью соответствующие бизнес-логике приложения.