Обработка возврата элемента

В Shopify Draggable управление возвратом элемента (revert) после завершения перетаскивания — одна из ключевых задач для создания интуитивного и корректного пользовательского интерфейса. Эта функциональность позволяет элементу вернуться на исходную позицию, если операция перетаскивания была отменена или не соответствует правилам размещения.


Свойство revert и его поведение

В Draggable revert — это опция, которую можно задать при инициализации Draggable или в событиях, связанных с окончанием перетаскивания. Она отвечает за анимацию возврата элемента:

const draggable = new Draggable(document.querySelectorAll('.draggable'), {
  draggable: '.item',
  revertOnSpill: true
});

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

  • revertOnSpill: true — элемент вернется на исходное место, если он был “выброшен” за пределы допустимой зоны.
  • revertOnSpill: false — элемент останется там, где его отпустили, даже если зона недопустимая.
  • Можно использовать функцию, возвращающую boolean, чтобы динамически контролировать возврат:
const draggable = new Draggable(document.querySelectorAll('.draggable'), {
  draggable: '.item',
  revertOnSpill: (dragEvent) => {
    return !dragEvent.dropTarget; // возвращаем элемент, если нет целевой зоны
  }
});

Методы для программного возврата элемента

Draggable предоставляет событие drag:stop, которое срабатывает после завершения перетаскивания. В обработчике события можно явно вызвать возврат элемента:

draggable.on('drag:stop', (event) => {
  if (!event.dropTarget) {
    event.source.style.transform = ''; // сброс transform
    // Можно вызвать дополнительную анимацию возврата
  }
});

При необходимости использовать плавную анимацию возвращения лучше сочетать CSS-переходы с программным сбросом позиции. Например:

.item {
  transition: transform 0.3s ease;
}
draggable.on('drag:stop', (event) => {
  if (!event.dropTarget) {
    event.source.style.transform = 'translate(0, 0)';
  }
});

Обработка сложных сценариев возврата

Иногда требуется, чтобы элемент возвращался только при определенных условиях:

  1. Проверка позиции элемента — если элемент за пределами допустимой зоны.
  2. Проверка состояния приложения — например, нельзя разрешить возврат, если другой элемент блокирует исходную позицию.
  3. Комбинированный подход с группами Draggable:
const containerA = document.querySelector('.container-a');
const containerB = document.querySelector('.container-b');

const draggable = new Draggable([containerA, containerB], {
  draggable: '.item',
  revertOnSpill: true
});

draggable.on('drag:stop', (event) => {
  if (event.dropTarget && event.dropTarget.matches('.container-b')) {
    // элемент можно оставить в контейнере B
    return;
  }
  // возврат к исходной позиции
  event.source.style.transform = 'translate(0, 0)';
});

Особенности взаимодействия с другими опциями Draggable

  • mirror — создает копию перетаскиваемого элемента. Возврат обычно применяется к исходному элементу, а не к зеркалу, поэтому важно синхронизировать стили.
  • sortables и containers — при использовании сортируемых списков возврат должен учитывать текущее положение элементов и индекс в списке.
  • Плавность анимации — рекомендуется использовать CSS-переходы, так как встроенные механизмы Draggable управляют только координатами transform.

Практические советы

  • Для динамического контроля возврата использовать функцию revertOnSpill вместо булевого значения.
  • Всегда сбрасывать transform после окончания анимации, чтобы элемент занимал корректное место в DOM.
  • При работе с несколькими контейнерами проверять dropTarget, чтобы избежать неожиданных перемещений.
  • Анимацию возврата можно комбинировать с событиями drag:start и drag:move для более естественного поведения.

Обработка возврата элемента в Draggable позволяет создавать интерфейсы, где перетаскивание остается предсказуемым и визуально плавным, обеспечивая правильное взаимодействие с пользователем и структурой DOM.