Vanilla JavaScript

Shopify Draggable — это библиотека на чистом JavaScript, предназначенная для создания интерактивных интерфейсов с возможностью перетаскивания, сортировки и управления списками элементов. Она работает без зависимостей от сторонних фреймворков и идеально подходит для реализации drag-and-drop в веб-приложениях, управляемых Vanilla JavaScript.

Библиотека строится вокруг трёх ключевых компонентов:

  1. Draggable – основной класс для создания перетаскиваемых элементов.
  2. Plugins – дополнительные функциональности, такие как сортировка, зеркальное отображение элементов, снэппинг.
  3. Events – система событий для отслеживания начала, движения и завершения перетаскивания.

Инициализация Draggable

Для создания базового draggable-элемента используется следующий синтаксис:

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

const draggable = new Draggable(document.querySelectorAll('.list'), {
  draggable: '.item',
  delay: 0,
  mirror: {
    constrainDimensions: true,
  }
});

Разбор параметров:

  • document.querySelectorAll('.list') – контейнеры, внутри которых элементы будут перетаскиваться.
  • draggable: '.item' – CSS-селектор для элементов, которые можно перетаскивать.
  • delay – задержка перед началом drag (в миллисекундах).
  • mirror – объект с настройками для «зеркала» (копии элемента при перетаскивании).

События Draggable

Draggable использует мощную систему событий, позволяющую отслеживать каждый этап взаимодействия:

  • drag:start – когда пользователь начал перетаскивать элемент.
  • drag:move – когда элемент перемещается.
  • drag:stop – когда завершилось перетаскивание.
  • mirror:created – когда создаётся визуальная копия элемента для перемещения.
  • sortable:stop – когда завершена сортировка элементов.

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

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

draggable.on('drag:stop', (event) => {
  console.log('Элемент отпущен:', event.source);
});

Каждое событие получает объект event, содержащий такие свойства, как source (исходный элемент), sensorEvent (оригинальное событие мыши/тача) и mirror (элемент-зеркало).


Плагины Draggable

Draggable поддерживает подключаемые плагины, расширяющие функциональность. Среди ключевых:

  1. Sortable – позволяет изменять порядок элементов в контейнере.
import { Sortable } from '@shopify/draggable';

const sortable = new Sortable(document.querySelectorAll('.list'), {
  draggable: '.item'
});
  1. Swappable – добавляет возможность обмена элементов между контейнерами.
import { Swappable } from '@shopify/draggable';

const swappable = new Swappable(document.querySelectorAll('.list'), {
  draggable: '.item',
  swapAnimation: {
    duration: 300,
    easingFunction: 'ease-in-out'
  }
});
  1. Droppable – позволяет создавать области, куда можно «бросать» элементы.
import { Droppable } from '@shopify/draggable';

const droppable = new Droppable(document.querySelectorAll('.drop-area'), {
  draggable: '.item'
});

Плагины можно комбинировать для реализации сложных интерфейсов с сортировкой, перетаскиванием между списками и визуальной анимацией.


Настройка зеркала (Mirror)

Зеркало — это копия перетаскиваемого элемента, которая следует за курсором:

const draggable = new Draggable(document.querySelectorAll('.list'), {
  draggable: '.item',
  mirror: {
    constrainDimensions: true,
    xAxis: true,
    yAxis: true
  }
});
  • constrainDimensions: true – зеркальная копия сохраняет размеры исходного элемента.
  • xAxis / yAxis – ограничение движения по конкретной оси.
  • Можно кастомизировать стиль зеркала через CSS: .draggable-mirror.

Работа с множественными контейнерами

Draggable поддерживает несколько контейнеров одновременно:

const draggable = new Draggable(
  document.querySelectorAll('.list, .another-list'), 
  { draggable: '.item' }
);

Элементы можно перетаскивать между разными списками без дополнительных настроек. При этом события sortable:stop и swappable:swapped помогут отслеживать изменения порядка и обмена элементов.


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

  • Event Delegation: Draggable использует делегирование событий, что уменьшает нагрузку при работе с большим числом элементов.
  • Минимизация DOM-операций: зеркала и анимации создаются динамически и удаляются сразу после окончания drag.
  • Использование CSS-переходов: плавность анимаций лучше обеспечивать через transform вместо top/left.

Интеграция с другими библиотеками

Draggable легко интегрируется с Vanilla JS-плагинами для:

  • Визуализации сеток (Masonry, CSS Grid)
  • Анимации (GSAP)
  • Форм управления и динамического обновления данных (Fetch API, Axios)

Пример совместимости с GSAP для анимации зеркала:

draggable.on('mirror:created', ({ mirror }) => {
  gsap.set(mirror, { opacity: 0.8, scale: 1.05 });
});

Практические рекомендации

  • Всегда использовать конкретные селекторы, чтобы не создавать draggable для лишних элементов.
  • Для сложных интерфейсов применять комбинацию Sortable + Swappable.
  • Поддерживать адаптивность на тач-устройствах, проверяя события touchstart и touchmove.
  • Контролировать события drag:stop, чтобы синхронизировать изменения с сервером или локальной моделью данных.

Draggable в Vanilla JavaScript предоставляет полный контроль над интерфейсом перетаскивания, позволяя создавать динамичные и отзывчивые пользовательские элементы без использования сторонних фреймворков.