Dragula — это легковесная библиотека для реализации drag-and-drop интерфейсов в браузере на чистом JavaScript. Основной принцип её работы — перенос элементов между контейнерами без необходимости написания большого объёма кода. Она управляет событиями мыши и касания, создаёт копии перетаскиваемых элементов и обновляет DOM автоматически.
Базовая инициализация Dragula выглядит так:
const drake = dragula([container1, container2]);
где container1 и container2 — DOM-элементы,
между которыми разрешён перенос элементов. После инициализации можно
использовать события Dragula, такие как
drag, drop, over,
out, cancel, для управления поведением
интерфейса.
Dragula позволяет гибко управлять тем, какие элементы могут быть
перетаскиваемыми. Для этого используется опция
invalid, которая принимает функцию. Эта
функция вызывается для каждого потенциального перетаскиваемого элемента
и должна возвращать true, если элемент нельзя
захватить, и false, если захват разрешён.
Пример использования:
const drake = dragula([container], {
invalid: function(el, handle) {
return el.classList.contains('no-drag');
}
});
В данном случае элементы с классом no-drag невозможно
перемещать. Параметры функции:
el — DOM-элемент, который пытаются перетащить.handle — элемент, на котором фактически произошёл клик
для начала drag. Часто совпадает с el, но может быть
потомком.Опция invalid позволяет реализовать сложные
условия блокировки, например:
Пример динамической блокировки:
const drake = dragula([container], {
invalid: function(el, handle) {
if (el.dataset.locked === 'true') return true;
if (handle.classList.contains('drag-handle')) return false;
return true;
}
});
Здесь элементы с атрибутом data-locked="true" нельзя
перемещать. Остальные элементы можно перемещать только через дочерний
элемент с классом drag-handle.
Даже если элемент заблокирован, Dragula всё равно генерирует события, но не разрешает перемещение. Например:
drake.on('drag', function(el) {
console.log('Начато перетаскивание:', el);
});
drake.on('cancel', function(el, container) {
console.log('Перетаскивание отменено для элемента:', el);
});
drag срабатывает при попытке начать перетаскивание
только разрешённых элементов.cancel срабатывает для всех элементов, которые не
удалось захватить (включая те, что заблокированы через
invalid).Это позволяет отслеживать действия пользователя и реализовать подсказки или визуальные эффекты для заблокированных элементов.
Блокировка заголовков и кнопок внутри элемента Часто в списках с drag-and-drop нужно запретить перетаскивание кнопок, иконок или заголовков:
const drake = dragula([container], {
invalid: function(el, handle) {
return handle.tagName === 'BUTTON' || handle.classList.contains('title');
}
});Блокировка элементов по роли или состоянию Если элемент должен быть статическим до определённого события:
const drake = dragula([container], {
invalid: function(el) {
return el.getAttribute('data-role') === 'fixed';
}
});Перетаскивание только за «ручку» Иногда нужно, чтобы элемент можно было перемещать только за специально помеченную область:
const drake = dragula([container], {
invalid: function(el, handle) {
return !handle.classList.contains('drag-handle');
}
});moves(el, source, handle, sibling) — опция,
определяющая, разрешено ли перемещение элемента. Она работает
совместно с invalid, и элемент будет
перетаскиваться только если invalid вернёт
false и moves вернёт true.copy — можно разрешить копирование элементов, но
заблокированные через invalid элементы копироваться не
будут.revertOnSpill — элементы, которые не были захвачены
из-за invalid, автоматически не участвуют в логике
«возврата при сбросе вне контейнера».Использование invalid позволяет создавать тонко
настраиваемый интерфейс drag-and-drop, где одни элементы
перетаскиваются, а другие остаются статичными, без сложного
вмешательства в DOM или отслеживания событий вручную.