Библиотека Dragula предоставляет мощный и гибкий механизм перетаскивания элементов между контейнерами, однако в реальных приложениях часто возникает необходимость накладывать ограничения на то, какие элементы можно перетаскивать, куда их можно помещать и при каких условиях допускается перемещение. Dragula предлагает несколько встроенных способов для управления такими ограничениями.
invalidМетод invalid позволяет определить, какие элементы не
подлежат перетаскиванию. Этот метод принимает функцию, которая получает
текущий элемент и возвращает true, если элемент нельзя
перетаскивать, и false, если перетаскивание разрешено.
Пример использования:
const drake = dragula([container1, container2], {
invalid: function(el, handle) {
// Запрет на перетаскивание элементов с классом 'no-drag'
return el.classList.contains('no-drag');
}
});
el — элемент, на котором инициируется
перетаскивание.handle — элемент, по которому
производится клик для начала перетаскивания. Может совпадать с
el или быть дочерним элементом.Использование invalid удобно для создания зон, где
перетаскивание запрещено, или для исключения из перетаскивания
конкретных элементов, таких как кнопки или заголовки карточек.
acceptsФункция accepts задаёт правила, куда элемент можно
помещать. Она вызывается каждый раз при попытке перемещения элемента в
другой контейнер и должна возвращать true, если вставка
разрешена, и false, если нет.
Пример ограничения по контейнерам:
const drake = dragula([container1, container2, container3], {
accepts: function(el, target, source, sibling) {
// Разрешаем перемещать элементы только в container2
return target === container2;
}
});
el — перетаскиваемый элемент.target — контейнер, в который пытаются
вставить элемент.source — исходный контейнер.sibling — элемент, перед которым
произойдёт вставка (null, если в конец).Функция accepts позволяет создавать сложные логики,
например, разрешать перемещение элементов только определённого типа или
предотвращать дублирование внутри контейнера.
movesФункция moves позволяет определить, по каким элементам
внутри перетаскиваемого блока разрешено инициировать перетаскивание. Это
особенно полезно, когда у карточки есть несколько интерактивных
элементов (кнопки, ссылки), которые не должны запускать
drag-and-drop.
Пример ограничения точки захвата:
const drake = dragula([container1, container2], {
moves: function(el, source, handle, sibling) {
// Разрешаем перетаскивать только по элементу с классом 'handle'
return handle.classList.contains('handle');
}
});
handle — элемент, по которому
пользователь нажимает и тянет.moves позволяет создавать удобный
пользовательский интерфейс, где перетаскивание начинается только за
специально выделенные области карточки.Dragula предоставляет возможность контролировать позицию вставки
через параметр sibling в функции accepts. Если
возвращается false для конкретного sibling,
элемент не будет вставлен перед ним. Это позволяет реализовать:
Пример закрепления первого элемента:
const drake = dragula([container], {
accepts: function(el, target, source, sibling) {
// Первый элемент нельзя передвигать
if (sibling && sibling === container.firstElementChild) return false;
return true;
}
});
Для удобного управления можно использовать кастомные атрибуты или
классы для элементов и проверять их в функциях invalid и
accepts.
Пример ограничения по типу:
const drake = dragula([container1, container2], {
accepts: function(el, target) {
// Разрешаем перемещать только элементы с data-type="draggable"
return el.dataset.type === "draggable";
}
});
Такой подход обеспечивает гибкость и масштабируемость, особенно если количество типов элементов в приложении большое.
Dragula позволяет ограничить количество элементов в целевом
контейнере через проверку target.children.length в функции
accepts.
Пример ограничения количества элементов:
const drake = dragula([container1, container2], {
accepts: function(el, target) {
// В контейнере не должно быть больше 5 элементов
return target.children.length < 5;
}
});
Это удобно для реализации досок задач, корзин товаров или любых списков с лимитом.
Иногда требуется запретить перемещение элементов вне исходного
контейнера. Это можно реализовать через accepts, проверяя
совпадение target и source:
const drake = dragula([container], {
accepts: function(el, target, source) {
return source === target;
}
});
Эта настройка позволяет реализовать сортировку внутри одного контейнера без возможности перемещать элементы наружу.
Функции invalid, moves и
accepts можно комбинировать для создания сложной логики
перетаскивания. Dragula применяет их в следующем порядке:
invalid — элемент полностью исключается из
перетаскивания.moves — определяется, можно ли инициировать
перетаскивание по данному handle.accepts — проверяется возможность вставки
элемента в выбранный контейнер и перед выбранным sibling.Такой подход позволяет реализовать практически любые ограничения на уровне интерфейса без модификации самой библиотеки.