Завершение перетаскивания

В библиотеке Muuri событие завершения перетаскивания элемента играет ключевую роль в управлении динамическими сетками. Оно позволяет отслеживать момент, когда пользователь закончил перемещать элемент, и выполнять дополнительные действия: обновление данных, анимацию, сохранение состояния и синхронизацию с внешними источниками.

Событие dragEnd

Muuri предоставляет встроенное событие dragEnd, которое срабатывает каждый раз, когда элемент перестает быть захваченным мышью или жестом сенсорного экрана. Его использование выглядит следующим образом:

const grid = new Muuri('.grid', {
  dragEnabled: true
});

grid.on('dragEnd', function(item) {
  console.log('Элемент завершил перетаскивание:', item.getElement());
});

Ключевые моменты:

  • item — объект типа Muuri.Item, представляющий перетащенный элемент.
  • item.getElement() возвращает DOM-элемент, с которым завершилось перетаскивание.
  • Событие вызывается после завершения анимации возврата элемента на сетку, если позиция изменилась.

Определение изменения позиции

После перетаскивания важно понимать, переместился ли элемент относительно других. Для этого у Muuri.Item есть методы:

  • getIndex() — возвращает текущий индекс элемента в сетке.
  • getGrid().getItems() — возвращает массив всех элементов сетки в текущем порядке.

Пример проверки:

grid.on('dragEnd', function(item) {
  const newIndex = item.getIndex();
  console.log('Новый индекс элемента:', newIndex);
});

Если необходимо определить, был ли элемент перемещен относительно других:

grid.on('dragEnd', function(item) {
  const previousIndex = item._previousIndex; // сохраняется вручную при dragStart
  const currentIndex = item.getIndex();
  if (previousIndex !== currentIndex) {
    console.log('Элемент изменил позицию:', previousIndex, '->', currentIndex);
  }
});

Сохранение состояния сетки

Для динамических приложений часто требуется сохранять порядок элементов после завершения перетаскивания. Обычно это делается с помощью сериализации массива идентификаторов:

function saveGridState() {
  const order = grid.getItems().map(item => item.getElement().dataset.id);
  localStorage.setItem('gridOrder', JSON.stringify(order));
}

grid.on('dragEnd', function(item) {
  saveGridState();
});

Особенности:

  • Можно использовать dataset.id для привязки к уникальному идентификатору элемента.
  • Состояние сохраняется локально или отправляется на сервер через AJAX.

Анимация и визуальная обратная связь

Muuri автоматически применяет анимацию при завершении перетаскивания, если включена опция layoutOnDragEnd. Это позволяет сглаживать перемещение элементов и предотвращает резкий «прыжок»:

const grid = new Muuri('.grid', {
  dragEnabled: true,
  layoutOnDragEnd: true,
  layout: {
    duration: 400,
    easing: 'ease'
  }
});
  • layout.duration — продолжительность анимации в миллисекундах.
  • layout.easing — функция сглаживания движения.

Комбинирование с другими событиями

Для сложных взаимодействий dragEnd можно использовать совместно с dragStart и move:

  • dragStart — сохраняет исходное положение элемента.
  • move — срабатывает при каждом шаге перемещения, позволяет обновлять подсказки или состояние интерфейса.
  • dragEnd — фиксирует окончательный результат и запускает обработку данных.

Пример комплексного использования:

grid.on('dragStart', function(item) {
  item._previousIndex = item.getIndex();
});

grid.on('move', function(item) {
  console.log('Элемент перемещается:', item.getElement());
});

grid.on('dragEnd', function(item) {
  const previous = item._previousIndex;
  const current = item.getIndex();
  if (previous !== current) {
    console.log('Позиция изменилась:', previous, '->', current);
  }
});

Рекомендации по производительности

  • Не выполнять тяжёлые вычисления напрямую внутри обработчика dragEnd.
  • Для обновления DOM или взаимодействия с сервером использовать requestAnimationFrame или отложенные вызовы.
  • Минимизировать количество вызовов getItems() при больших сетках — хранить актуальный порядок элементов локально и обновлять его при необходимости.

Итоговая функциональность

Правильное использование события dragEnd позволяет:

  • Отслеживать завершение перетаскивания и изменение позиции.
  • Обеспечивать плавную анимацию возврата элементов.
  • Сохранять состояние сетки для динамических интерфейсов.
  • Интегрировать сетку с внешними источниками данных и сервером.

Эта функциональность делает Muuri мощным инструментом для реализации интерактивных и адаптивных сеток с поддержкой drag-and-drop.