Dragula — это библиотека для организации перетаскивания элементов между контейнерами и внутри одного контейнера. Она отличается минималистичным API, простотой интеграции и возможностью работать как с одиночными списками, так и с группами контейнеров. Основная цель — сделать взаимодействие с DOM интуитивным, не требуя сложной настройки событий.
Контейнеры и элементы Контейнер — это любой элемент DOM, который будет содержать перетаскиваемые элементы. Элемент — это отдельный объект внутри контейнера, который можно перетаскивать. Dragula автоматически обрабатывает перетаскивание элементов, изменяя их позицию в DOM.
const containers = [document.getElementById('list1'), document.getElementById('list2')];
const drake = dragula(containers);
В данном примере создаются два контейнера, между которыми можно
перемещать элементы. Dragula отслеживает события drag,
drop, over, out и
cancel, позволяя гибко реагировать на действия
пользователя.
Ограничение на перетаскивание Для ограничения
перетаскиваемых элементов используется функция moves:
const drake = dragula(containers, {
moves: function (el, source, handle, sibling) {
return handle.classList.contains('handle'); // перетаскивать только по специальной ручке
}
});
Контроль над сбросом элементов Функция
accepts позволяет определить, можно ли перемещать элемент в
конкретный контейнер:
drake = dragula(containers, {
accepts: function (el, target, source, sibling) {
return target.id !== 'list2'; // запрещаем перемещать в list2
}
});
Копирование элементов Dragula поддерживает
копирование вместо перемещения через опцию copy:
drake = dragula(containers, {
copy: true
});
Это позволяет использовать один контейнер как источник шаблонов, не изменяя его содержимое при переносе элементов.
Dragula предоставляет богатый набор событий для отслеживания действий пользователя:
drag: начинается перетаскивание элементаdrop: элемент сброшен в контейнерover: элемент наведен на контейнерout: элемент покинул контейнерcancel: перетаскивание отмененоcloned: создаётся копия элемента (при
copy: true)Пример подписки на события:
drake.on('drop', function (el, target, source, sibling) {
console.log(`Элемент ${el.textContent} перемещён из ${source.id} в ${target.id}`);
});
События можно использовать для обновления состояния приложения или отправки данных на сервер после перемещения элементов.
Для реализации сортировки Dragula автоматически переставляет элементы
в контейнере при перетаскивании. Позиция элемента определяется
положением курсора относительно соседних элементов
(sibling).
drake.on('drop', function(el, target, source, sibling) {
if (sibling) {
target.insertBefore(el, sibling);
} else {
target.appendChild(el);
}
});
Эта логика позволяет сохранять порядок элементов и динамически переставлять их в DOM без дополнительных вычислений.
Dragula поддерживает работу с несколькими контейнерами одновременно, что удобно для реализации интерфейсов с группировкой элементов по категориям. Группы контейнеров задаются массивом элементов при инициализации.
const groups = [
document.getElementById('group1'),
document.getElementById('group2'),
document.getElementById('group3')
];
const drake = dragula(groups, {
accepts: function (el, target, source, sibling) {
return target.dataset.group === el.dataset.group; // только внутренняя группа
}
});
Такой подход позволяет ограничить перемещение элементов только внутри одной группы, сохраняя структурированность данных.
Контейнеры и элементы не обязаны существовать при инициализации
Dragula. Можно динамически добавлять элементы и контейнеры, после чего
вызвать метод drake.containers.push(newContainer) для
включения нового контейнера в обработку перетаскивания.
const newContainer = document.createElement('div');
newContainer.id = 'list3';
document.body.appendChild(newContainer);
drake.containers.push(newContainer);
Эта возможность особенно полезна для интерфейсов с подгрузкой контента по мере взаимодействия пользователя.
Dragula автоматически добавляет классы:
gu-mirror — копия элемента, следящая за курсоромgu-transit — перетаскиваемый элементgu-hide — скрывает оригинальный элемент при
копированииДополнительно можно использовать CSS для изменения внешнего вида контейнеров и элементов в зависимости от состояния перетаскивания.
.gu-transit {
opacity: 0.5;
border: 1px dashed #000;
}
.gu-mirror {
box-shadow: 2px 2px 5px rgba(0,0,0,0.3);
}
Dragula минимально вмешивается в DOM и не создает лишних операций, что обеспечивает высокую производительность даже при большом количестве элементов. Для больших списков рекомендуется:
requestAnimationFrame для любых
дополнительных визуальных изменений,drag и
drop,moves,
accepts, copy).drop.Эта структура позволяет создавать интерфейсы с интерактивными списками, перемещаемыми элементами и четкой группировкой без необходимости писать сложные алгоритмы сортировки вручную.