Что такое Shopify Draggable

Shopify Draggable — это библиотека на JavaScript, предназначенная для реализации функциональности перетаскивания элементов на веб-странице. Она обеспечивает гибкий API для создания drag-and-drop интерфейсов без необходимости работы с низкоуровневым mousedown, mousemove и mouseup. Основная цель библиотеки — сделать взаимодействие с DOM-интерфейсом интуитивным и расширяемым.

Ключевые особенности:

  • Модульная архитектура: Draggable разделён на несколько плагинов (Plugins), каждый из которых добавляет отдельную функциональность: сортировка, swappable, скроллинг и т.д.
  • Событийная модель: Все действия сопровождаются событиями, которые позволяют реагировать на начало перетаскивания, изменение позиции элемента и завершение операции.
  • Поддержка touch и mouse: Библиотека автоматически обрабатывает как мышь, так и сенсорные устройства, без необходимости дополнительной настройки.

Основные классы и объекты

Draggable

Основной класс библиотеки. Создание нового экземпляра выглядит так:

import { Draggable } from '@shopify/draggable';

const draggable = new Draggable(document.querySelectorAll('.draggable-item'), {
  draggable: '.item',
  delay: 0,
  mirror: {
    constrainDimensions: true
  }
});
  • document.querySelectorAll(‘.draggable-item’) — контейнеры, внутри которых будут перетаскиваться элементы.
  • draggable: ‘.item’ — CSS-селектор элементов, которые можно перемещать.
  • delay — задержка перед началом перетаскивания (в мс).
  • mirror — объект настройки зеркального элемента, который визуально повторяет перетаскиваемый объект.

Plugins

Draggable поддерживает плагины, расширяющие базовую функциональность:

  • Sortable — позволяет менять порядок элементов внутри контейнера.
  • Swappable — даёт возможность обмениваться местами с другими элементами при перетаскивании.
  • Collidable — проверяет столкновения элементов и контейнеров.
  • Droppable — позволяет определить области, куда можно «бросать» элементы.

Пример подключения плагина Sortable:

import { Sortable } from '@shopify/draggable';

const sortable = new Sortable(document.querySelectorAll('.sortable-container'), {
  draggable: '.sortable-item',
  delay: 100
});

Работа с событиями

Draggable предоставляет богатый набор событий:

  • drag:start — инициируется при начале перетаскивания.
  • drag:move — вызывается при каждом движении перетаскиваемого элемента.
  • drag:stop — срабатывает по завершении перетаскивания.
  • sortable:sort — используется в Sortable, уведомляет о завершении сортировки.
  • droppable:over / droppable:out — события для Droppable при наведении на целевую область и выходе из неё.

Пример обработки события:

draggable.on('drag:start', (event) => {
  console.log('Начало перетаскивания:', event.data.source);
});

sortable.on('sortable:sort', (event) => {
  console.log('Элемент отсортирован:', event.data.dragEvent.source);
});

Каждое событие содержит объект data, который предоставляет доступ к:

  • source — исходный элемент, который перетаскивается.
  • mirror — зеркальный элемент, создаваемый библиотекой для визуализации.
  • over — элемент, над которым в данный момент находится перетаскиваемый объект.
  • oldIndex / newIndex — индексы элемента до и после сортировки.

Настройка зеркального элемента (Mirror)

Зеркальный элемент (mirror) используется для визуализации перетаскивания, не влияя на исходный DOM-элемент. Настройки:

  • constrainDimensions — сохраняет размеры исходного элемента.
  • xAxis / yAxis — ограничение движения по горизонтали или вертикали.
  • appendTo — задаёт контейнер, в который добавляется зеркальный элемент.

Пример:

const draggable = new Draggable('.draggable', {
  draggable: '.item',
  mirror: {
    constrainDimensions: true,
    appendTo: 'body'
  }
});

Сортировка элементов

Использование Sortable позволяет создавать динамически изменяемые списки. Важные методы и свойства:

  • getDraggableElements() — возвращает массив всех перетаскиваемых элементов.
  • destroy() — удаляет экземпляр и очищает все обработчики.
  • on(‘sortable:sorted’, callback) — событие по завершении сортировки.

Пример:

sortable.on('sortable:sorted', (event) => {
  const newOrder = Array.from(event.data.container.children).map(el => el.dataset.id);
  console.log('Новый порядок элементов:', newOrder);
});

Советы по производительности

  • Использовать селекторы для контейнеров, а не для всех элементов страницы.
  • Ограничивать количество зеркальных элементов одновременно.
  • В больших списках применять делегирование событий через контейнер.
  • Удалять неиспользуемые экземпляры Draggable с помощью метода destroy().

Расширенные возможности

  • Nested Drag and Drop — поддержка вложенных контейнеров.
  • Custom plugins — создание собственных плагинов через наследование от базового класса Plugin.
  • Integration with frameworks — библиотека легко интегрируется с React, Vue, Angular через ref или querySelector.

Shopify Draggable сочетает простоту базового API с гибкостью событий и плагинов, что позволяет создавать сложные drag-and-drop интерфейсы с минимальным количеством кода.