Dragula — это лёгкая и удобная библиотека для реализации
drag-and-drop интерфейсов на чистом JavaScript. Одним из ключевых
инструментов, обеспечивающих гибкий контроль над поведением
перетаскивания, является опция moves. Она позволяет
определить, какие элементы могут быть перетаскиваемыми,
а какие — нет, исходя из любых условий.
movesОпция moves является функцией, которая вызывается каждый
раз, когда пользователь пытается начать перетаскивание элемента. Функция
имеет следующую сигнатуру:
function moves(el, source, handle, sibling) {
// возвращает true или false
}
el или его потомок, с которого
пользователь начал перетаскивать.Функция должна возвращать логическое значение:
true, если перетаскивание разрешено, и false,
если запрещено.
Обычно moves применяется для ограничения перетаскивания
на основе класса элемента или контейнера:
dragula([document.querySelector('#container')], {
moves: function(el, source, handle, sibling) {
// Только элементы с классом 'draggable' можно перемещать
return el.classList.contains('draggable');
}
});
В данном примере любые элементы без класса draggable
будут неподвижны.
Иногда требуется, чтобы перетаскивание инициировалось только при
взаимодействии с определённой частью элемента, например, иконкой или
заголовком карточки. Для этого используют проверку
handle:
dragula([document.querySelector('#tasks')], {
moves: function(el, source, handle, sibling) {
// Разрешаем перетаскивание только через элемент с классом 'handle'
return handle.classList.contains('handle');
}
});
Таким образом, элемент не станет draggable при клике на любую другую область.
moves позволяет учитывать не только свойства элемента,
но и контейнера. Это полезно для создания сложных интерфейсов, где
разные секции имеют разные правила:
dragula([container1, container2], {
moves: function(el, source, handle, sibling) {
if (source.id === 'locked-container') {
return false; // полностью запрещаем перетаскивание из контейнера с id 'locked-container'
}
return true;
}
});
Здесь элементы из locked-container не могут быть
перемещены, а из остальных контейнеров — могут.
Можно использовать любые условия для ограничения перетаскивания. Например, запрещать перетаскивание заблокированных элементов:
dragula([document.querySelector('#list')], {
moves: function(el, source, handle, sibling) {
// Проверка пользовательского атрибута data-lock
return el.getAttribute('data-lock') !== 'true';
}
});
Эта гибкость позволяет создавать динамические правила в зависимости от состояния интерфейса или бизнес-логики.
Часто требуется учитывать одновременно несколько критериев: класс, контейнер, состояние элемента и ручку. В этом случае условия объединяются через логические операторы:
dragula([containerA, containerB], {
moves: function(el, source, handle, sibling) {
const isHandleCorrect = handle.classList.contains('drag-handle');
const isNotLocked = el.getAttribute('data-locked') !== 'true';
const allowedContainer = source.id !== 'forbidden';
return isHandleCorrect && isNotLocked && allowedContainer;
}
});
Такой подход обеспечивает тонкий контроль над перетаскиванием, исключая нежелательные действия.
&& и
||, чтобы правила были гибкими и
масштабируемыми.Опция moves — один из самых мощных инструментов Dragula,
позволяющий реализовать сложные интерфейсы с точным контролем, кто и как
может перетаскивать элементы. Правильная организация проверок внутри
этой функции делает интерфейс интуитивным и безопасным, исключая
случайные перемещения.