Dragula — это легковесная библиотека для реализации функциональности drag-and-drop на веб-страницах. Она обеспечивает простое создание интерактивных интерфейсов, где элементы можно перемещать между контейнерами без необходимости работы с низкоуровневыми событиями мыши и touch-событиями. Dragula особенно удобна для динамических интерфейсов, таких как списки задач, панели управления или интерактивные таблицы.
Инициализация Dragula происходит через вызов функции
dragula(containers, options), где containers —
массив DOM-элементов или селекторов контейнеров, а options
— объект с настройками поведения. Основные параметры, влияющие на работу
drag-and-drop, включают:
moves — функция, определяющая, какие элементы можно
перетаскивать.accepts — функция, определяющая, в какие контейнеры
элемент может быть помещен.copy — логический флаг, указывающий, создается ли копия
перетаскиваемого элемента.revertOnSpill — откат элемента на исходное место при
случайном отпускании вне контейнера.Функция moves(el, source, handle, sibling) позволяет
гибко ограничивать возможность перетаскивания. Параметры функции:
el — перетаскиваемый элемент.source — контейнер, из которого осуществляется
перетаскивание.handle — элемент, по которому пользователь кликнул для
начала drag.sibling — элемент, перед которым будет вставлен
перетаскиваемый элемент, если операция успешна.Пример ограничения перетаскивания только по специальной «ручке»:
dragula([container1, container2], {
moves: function(el, source, handle, sibling) {
return handle.classList.contains('drag-handle');
}
});
Функция accepts(el, target, source, sibling) управляет
логикой попадания элементов в контейнеры. Это позволяет создавать
сложные правила, например, запрещать перемещение элементов с
определенным классом в определенные контейнеры.
dragula([container1, container2], {
accepts: function(el, target, source, sibling) {
return !el.classList.contains('locked');
}
});
Dragula генерирует набор событий, которые позволяют отслеживать жизненный цикл перетаскивания:
drag — срабатывает при начале перетаскивания.drop — срабатывает при успешной вставке элемента в
контейнер.over — когда элемент наведен над контейнером.out — когда элемент покидает контейнер.cancel — когда перетаскивание отменено.remove — когда элемент удален из контейнера при
removeOnSpill: true.События удобно использовать для валидации пользовательских действий. Например, можно проверять, соответствует ли вставка определенным правилам бизнес-логики:
drake.on('drop', function(el, target, source, sibling) {
if (!validateDrop(el, target)) {
source.insertBefore(el, sibling); // возвращаем элемент обратно
}
});
Основная задача Dragula в контексте валидации — это предотвращение некорректного перемещения элементов и обеспечение целостности данных. Валидация может выполняться на нескольких уровнях:
moves
можно запретить начинать drag для элементов, которые не должны быть
изменены.accepts можно
проверять типы контейнеров, допустимые позиции и свойства элемента.drop событие): можно
проводить дополнительную проверку данных и при необходимости откатывать
перемещение.Пример комплексной проверки:
dragula([todoList, completedList], {
moves: function(el, source) {
return !el.classList.contains('locked');
},
accepts: function(el, target) {
if (target.id === 'completed' && el.dataset.priority === 'high') {
return false; // нельзя перемещать элементы с высоким приоритетом
}
return true;
}
}).on('drop', function(el, target, source, sibling) {
if (target.id === 'completed' && el.dataset.dueDate < Date.now()) {
source.insertBefore(el, sibling); // откат для просроченных задач
}
});
Dragula предоставляет базовые инструменты, но их можно комбинировать с пользовательскими функциями валидации:
Для удобства можно создавать вспомогательные функции:
function validateDrop(el, target) {
if (target.children.length >= 5) return false;
if (el.dataset.type !== target.dataset.accept) return false;
return true;
}
Затем интегрировать их в Dragula:
drake.on('drop', function(el, target, source, sibling) {
if (!validateDrop(el, target)) {
source.insertBefore(el, sibling);
}
});
При динамическом добавлении контейнеров или элементов важно повторно
инициализировать Dragula или использовать делегированные события.
Dragula автоматически не отслеживает новые DOM-узлы, поэтому новые
контейнеры должны быть добавлены в массив containers через
метод drake.containers.push(newContainer).
Это обеспечивает постоянную валидацию для всех элементов интерфейса, независимо от того, были ли они на странице изначально или созданы динамически.
Dragula подходит для:
Правильное сочетание moves, accepts и
обработки событий drop обеспечивает строгую валидацию
пользовательского ввода, предотвращает некорректные действия и сохраняет
целостность данных на фронтенде.