Shopify Draggable — это библиотека для реализации
перетаскивания элементов в веб-интерфейсах на чистом JavaScript без
необходимости использования jQuery. В основе её работы лежат
события drag-and-drop, которые обеспечивают гибкость в
построении интерфейсов с сортировкой, перемещением и групповыми
действиями над элементами.
Ключевые компоненты библиотеки:
Для создания интерактивного списка используется базовый конструктор:
import { Draggable } from '@shopify/draggable';
const draggable = new Draggable(document.querySelectorAll('.draggable-container'), {
draggable: '.draggable-item',
delay: 0,
mirror: {
constrainDimensions: true
}
});
Ключевые моменты:
document.querySelectorAll('.draggable-container') —
контейнер, внутри которого находятся перетаскиваемые элементы.draggable: '.draggable-item' — селектор элементов,
которые будут перетаскиваться.delay — задержка перед началом перетаскивания, полезна
для предотвращения случайных срабатываний.mirror — объект настроек зеркального отображения:
constrainDimensions ограничивает размеры зеркала исходными
размерами элемента.Draggable позволяет подключать плагины для расширения возможностей:
Позволяет изменять порядок элементов внутри контейнера.
import { Sortable } from '@shopify/draggable';
const sortable = new Sortable(document.querySelectorAll('.sortable-container'), {
draggable: '.sortable-item',
delay: 100
});
Особенности:
sortable:stop, позволяющее
реагировать на завершение перемещения.Swappable для обмена элементов.Обеспечивает возможность обмена местами элементов при перетаскивании:
import { Swappable } from '@shopify/draggable';
const swappable = new Swappable(document.querySelectorAll('.swappable-container'), {
draggable: '.swappable-item',
delay: 50
});
События Swappable:
swappable:start — начало перетаскивания.swappable:swapped — элементы успешно обменялись
местами.swappable:stop — завершение операции.Создает зеркальное отображение перетаскиваемого элемента, чтобы пользователь видел визуальную копию, не трогая оригинал.
import { Mirror } from '@shopify/draggable';
const draggableWithMirror = new Draggable(document.querySelectorAll('.mirror-container'), {
draggable: '.mirror-item',
mirror: {
appendTo: 'body',
constrainDimensions: true
},
plugins: [Mirror]
});
Ключевые параметры:
appendTo — указывает, куда добавлять зеркальный элемент
в DOM.constrainDimensions — сохраняет размеры оригинала.Sortable,
Swappable.Draggable предоставляет гибкую систему событий:
| Событие | Описание |
|---|---|
drag:start |
Начало перетаскивания элемента |
drag:move |
Элемент перемещается, можно обновлять интерфейс |
drag:stop |
Перетаскивание завершено |
mirror:created |
Зеркальный элемент создан |
sortable:sorted |
Элемент отсортирован внутри контейнера |
swappable:swapped |
Произошел обмен элементов |
Пример использования событий:
draggable.on('drag:start', (evt) => {
console.log('Начало перетаскивания:', evt.source);
});
draggable.on('drag:stop', (evt) => {
console.log('Перетаскивание завершено');
});
События позволяют реализовать сложные сценарии, такие как динамическая валидация позиции элемента, подсветка допустимых зон или обновление состояния приложения на лету.
Draggable поддерживает композицию возможностей, позволяя использовать несколько плагинов одновременно. Например, можно создать интерфейс, где элементы сортируются и одновременно отображается зеркало:
const draggable = new Draggable(document.querySelectorAll('.complex-container'), {
draggable: '.complex-item',
plugins: [Sortable, Mirror]
});
Это даёт возможность:
Можно создавать собственные плагины, наследуя базовый функционал Draggable:
import { AbstractPlugin } from '@shopify/draggable';
class HighlightPlugin extends AbstractPlugin {
attach() {
this.draggable.on('drag:start', this.onStart);
}
detach() {
this.draggable.off('drag:start', this.onStart);
}
onStart(evt) {
evt.source.style.border = '2px solid red';
}
}
Особенности кастомных плагинов:
AbstractPlugin обеспечивает доступ к
объекту Draggable и его событиям.attach и detach управляют
подключением и отключением плагина.Draggable поддерживает селекцию контейнеров и зон, куда можно перемещать элементы:
const draggable = new Draggable(document.querySelectorAll('.container'), {
draggable: '.item',
delay: 50,
draggableClass: 'is-dragging'
});
draggable.on('drag:move', (evt) => {
const allowedZones = document.querySelectorAll('.drop-zone');
if (!Array.from(allowedZones).some(zone => zone.contains(evt.sensorEvent.target))) {
evt.cancel();
}
});
Преимущества такого подхода:
Зеркальный элемент (mirror) может быть кастомизирован
для сложных интерфейсов:
xAxis и yAxis — ограничение движения по
оси.scale — масштаб зеркала при перетаскивании.mirror:created и drag:stop для плавного
возврата элемента.Пример с масштабированием:
draggable.on('mirror:created', (evt) => {
evt.mirror.style.transform = 'scale(1.1)';
});
Эти возможности позволяют создавать интерактивные, гибкие и визуально насыщенные интерфейсы с перетаскиваемыми элементами, где каждая операция полностью контролируется событиями и расширениями Draggable.