В библиотеке Muuri операция перетаскивания
(drag) управляется через встроенный механизм
drag-событий. Иногда возникает необходимость
отменить текущую операцию перетаскивания — например,
при нарушении условий перетаскивания, при недостаточном перемещении
элемента или при логике интерфейса, которая запрещает перенос в
определённую область.
dragStart и метода drag.cancel()Muuri предоставляет метод cancel() у
объекта drag, который позволяет прекратить текущее
перетаскивание до завершения. Типичный сценарий выглядит
так:
const grid = new Muuri('.grid', {
dragEnabled: true
});
grid.on('dragStart', (item, event) => {
// Пример условия: запрет перетаскивания, если элемент имеет класс 'fixed'
if (item.getElement().classList.contains('fixed')) {
item.getGrid().drag.cancel(item);
}
});
Ключевые моменты:
item.getGrid() возвращает объект сетки Muuri, к
которому принадлежит элемент.drag.cancel(item) прерывает текущее
перетаскивание элемента, возвращая его на исходное место.dragStart срабатывает до физического
перемещения элемента, поэтому отмена здесь предотвращает любые
визуальные сдвиги.Иногда нужно отменить перетаскивание уже во время
движения. Для этого используется событие
dragMove:
grid.on('dragMove', (item, event) => {
const position = item.getDrag().getTranslate();
// Отмена, если элемент пересёк запрещённую область
if (position.left > 500) {
item.getGrid().drag.cancel(item);
}
});
Особенности работы:
item.getDrag().getTranslate() возвращает текущую
координату {left, top} элемента.drag.cancel(item) может быть вызван многократно —
Muuri корректно обработает повторные вызовы без ошибок.При отмене перетаскивания Muuri срабатывают соответствующие события:
dragEnd — срабатывает даже при отмене. Параметр
isCanceled указывает на отмену.move и layoutEnd могут быть вызваны в
зависимости от конфигурации сетки.Пример использования с проверкой отмены:
grid.on('dragEnd', (item) => {
if (item.isDragging()) {
console.log('Перетаскивание отменено');
}
});
Muuri позволяет отменять drag не только через события, но и через прямой вызов метода для элементов в любой момент:
const item = grid.getItems()[0];
grid.drag.cancel(item);
Это полезно для сценариев:
drag.cancel() только после
dragStart, иначе элемент может быть в состоянии,
когда отмена не будет корректно применена.translate для анимаций и
позиции элементов.grid.on('dragStart', (item) => {
if (item.getElement().dataset.locked === 'true') {
item.getGrid().drag.cancel(item);
}
});
grid.on('dragMove', (item) => {
const pos = item.getDrag().getTranslate();
if (pos.top < 0 || pos.left < 0) {
item.getGrid().drag.cancel(item);
}
});
grid.on('dragEnd', (item) => {
if (item.isDragging()) {
console.log('Элемент не был перемещён');
}
});
Этот пример показывает, как сочетать условия на старте drag, проверку позиции во время движения и обработку завершения для полного контроля над отменой операции.
Использование drag.cancel() в сочетании с событиями
dragStart, dragMove и dragEnd
обеспечивает:
Методы Muuri делают отмену drag гибкой и предсказуемой, обеспечивая надёжное управление интерактивными элементами в любой сетке.