Dragula — это лёгкая и удобная библиотека для реализации функционала drag-and-drop в веб-приложениях. Она позволяет перетаскивать элементы между контейнерами, а также внутри одного контейнера, обеспечивая простое управление событиями и состояниями. Основной принцип работы Dragula заключается в инициализации контейнеров, к которым применяются drag-операции, и подписке на события, сопровождающие перемещение элементов.
Пример базовой инициализации:
const container = document.querySelector('#container');
const drake = dragula([container]);
Здесь drake — объект Dragula, через который управляются
все операции перетаскивания.
Dragula предоставляет ряд событий, которые фиксируют различные моменты drag-and-drop процесса:
drag: элемент начал перетаскиваться.drop: элемент был сброшен в контейнер.over и out: элемент вошёл или вышел из
контейнера.cancel: операция перетаскивания была отменена.cloned: элемент был клонирован.Обработчики событий назначаются следующим образом:
drake.on('drop', (el, target, source, sibling) => {
console.log('Элемент перемещён', el);
});
Dragula позволяет настраивать правила перетаскивания:
Пример с настройкой правил:
const drake = dragula([container1, container2], {
copy: true,
accepts: (el, target, source, sibling) => !target.classList.contains('no-drop')
});
Memory leak (утечка памяти) в контексте Dragula чаще всего возникает из-за оставшихся подписок на события или неудалённых DOM-элементов, которые продолжают удерживаться в памяти. Основные источники утечек:
drake.on создаёт ссылку на функцию, которая хранится в
объекте drake. Если объект Dragula удалён, но обработчики
остались, память не освобождается.Используется метод destroy() для полного удаления всех
подписок и очистки внутренних структур:
drake.destroy();
Это освобождает все ссылки на DOM-элементы и события, предотвращая накопление ненужной памяти.
Если требуется выборочная очистка обработчиков:
function onDrop(el) {
console.log('Элемент перемещён', el);
}
drake.on('drop', onDrop);
// Позже, при необходимости очистки:
drake.off('drop', onDrop);
Метод off снимает конкретный обработчик, позволяя
избежать удержания ненужных ссылок.
Перед созданием нового экземпляра Dragula для контейнера нужно убедиться, что предыдущий экземпляр уничтожен:
if (drake) {
drake.destroy();
}
drake = dragula([container]);
При работе с динамическими контейнерами желательно избегать прямого
замыкания на элементы страницы. Вместо этого хранить только
идентификаторы или делегировать события через drake:
drake.on('drop', (el, target) => {
const id = el.dataset.id;
processElementById(id);
});
destroy() при удалении контейнера из
DOM.off() для удаления ненужных обработчиков,
если объект Dragula продолжает существовать.Эти подходы обеспечивают эффективное использование памяти, предотвращают утечки и позволяют масштабировать drag-and-drop функционал без риска постепенного замедления приложения.