Библиотека Shopify Draggable предоставляет гибкий механизм для реализации drag-and-drop интерфейсов в веб-приложениях. Одной из ключевых возможностей является отмена перетаскивания — предотвращение перемещения элемента в случае определённых условий или возврат элемента в исходное положение после неудачной попытки.
drag:start для контроля начала перетаскиванияShopify Draggable позволяет перехватывать момент начала
перетаскивания с помощью события drag:start. Это событие
передаёт объект события с информацией о целевом элементе и
контейнере.
import { Draggable } from '@shopify/draggable';
const draggable = new Draggable(document.querySelectorAll('.draggable-container'), {
draggable: '.draggable-item',
});
draggable.on('drag:start', (event) => {
const element = event.source;
// Условие для отмены перетаскивания
if (element.dataset.locked === 'true') {
event.cancel();
}
});
Ключевые моменты:
event.source — элемент, который пытаются
перетащить.event.cancel() — метод, который полностью отменяет
действие drag.drag:moveИногда необходимо разрешить перетаскивание, но предотвратить
перемещение за пределы допустимой зоны. Событие drag:move
позволяет контролировать текущую позицию элемента и, при необходимости,
останавливать перетаскивание.
draggable.on('drag:move', (event) => {
const currentX = event.sensorEvent.clientX;
const currentY = event.sensorEvent.clientY;
// Запретить движение за пределы контейнера
const container = event.source.parentElement.getBoundingClientRect();
if (currentX < container.left || currentX > container.right ||
currentY < container.top || currentY > container.bottom) {
event.cancel();
}
});
Примечание: Отмена drag:move
предотвращает дальнейшее перемещение элемента, но не завершает сам drag,
поэтому после возвращения в допустимую область перетаскивание
продолжится.
drag:stopЕсли требуется вернуть элемент в исходное положение после завершения
drag (например, если пользователь отпустил элемент вне разрешённой
зоны), событие drag:stop предоставляет необходимую
информацию:
draggable.on('drag:stop', (event) => {
const element = event.source;
const originalParent = element.dataset.originalParent;
if (!event.overContainer || event.overContainer.dataset.reject === 'true') {
// Возврат в исходное положение
element.style.transform = '';
originalParent.appendChild(element);
}
});
Советы по реализации возврата:
drag:start.transform или абсолютное
позиционирование для плавного возврата.transition для
визуального эффекта возврата.Draggable позволяет инициировать отмену drag программно, не дожидаясь событий мыши:
draggable.cancel(); // Отменяет текущее перетаскивание
Эта функция полезна в сложных сценариях, где нужно отменять действия на основе внешних условий, например, проверки состояния приложения или взаимодействия с другими компонентами интерфейса.
Для контроля, где элемент может быть перетащен, используются
containers и опции droppable. В комбинации
с отменой drag можно реализовать строгие правила перемещения:
const droppable = new Draggable(document.querySelectorAll('.draggable-container'), {
draggable: '.draggable-item',
delay: 100, // предотвращение случайных drag
});
droppable.on('droppable:over', (event) => {
if (event.over.dataset.reject === 'true') {
event.cancel(); // запрещает "высадку" элемента
}
});
Особенности:
droppable:over и droppable:out помогают
контролировать, где элемент можно оставить.Отмена перетаскивания необходима в следующих случаях:
Эта функциональность позволяет создавать интуитивные, безопасные и управляемые drag-and-drop интерфейсы, полностью контролируя, где и когда элементы могут быть перемещены, а также возвращены на исходное место в случае нарушений правил.