Для работы с Shopify Draggable необходимо подключить
саму библиотеку. Обычно это делается через пакет
@shopify/draggable в проекте на npm или через CDN:
import { Sortable } from '@shopify/draggable';
// или через CDN
// <script src="https://cdn.jsdelivr.net/npm/@shopify/draggable@1.0.0-beta.8/lib/draggable.bundle.js"></script>
После подключения создаётся новый экземпляр Sortable,
который отвечает за перетаскивание элементов внутри контейнера. Базовый
синтаксис:
const sortable = new Sortable(document.querySelectorAll('.container'), {
draggable: '.item',
});
Здесь:
document.querySelectorAll('.container') — выбирает
контейнеры, внутри которых будет работать сортировка.draggable: '.item' — задаёт элементы, которые можно
перетаскивать.Sortable поддерживает множество опций, которые позволяют гибко настроить поведение:
draggable – селектор элементов для
перетаскивания.
handle – селектор внутри элемента, за который
пользователь может «схватить» объект.
delay – задержка перед активацией перетаскивания (в
миллисекундах).
mirror – объект с настройками зеркального элемента
(копии перетаскиваемого объекта).
constrainDimensions: true – зеркальный элемент
сохраняет размеры оригинала.classes – объект для переопределения классов
CSS:
sortable: 'my-sortable-class'draggable: 'my-draggable-class'dragging: 'my-dragging-class'Пример расширенной инициализации с пользовательским handle и зеркалом:
const sortable = new Sortable(document.querySelectorAll('.container'), {
draggable: '.item',
handle: '.handle',
delay: 150,
mirror: {
constrainDimensions: true,
},
classes: {
dragging: 'dragging',
sortable: 'sortable-container',
draggable: 'draggable-item',
},
});
Sortable предоставляет богатый набор событий, которые можно использовать для управления логикой перетаскивания:
sortable:start – срабатывает при начале
перетаскивания.sortable:sort – вызывается каждый раз, когда элемент
перемещается в новом порядке.sortable:stop – срабатывает при завершении
перетаскивания.sortable:sorted – окончательная перестановка
элемента.sortable:mirror:created – создание зеркального
элемента.sortable:mirror:destroyed – удаление зеркального
элемента.Пример использования событий:
sortable.on('sortable:start', (event) => {
console.log('Начало перетаскивания:', event.data.dragEvent.source);
});
sortable.on('sortable:sorted', (event) => {
console.log('Элемент перемещён:', event.data.newIndex);
});
При перетаскивании Sortable создаёт визуальную копию элемента — mirror, которая следует за курсором. Управление зеркалом позволяет задавать ограничения и анимацию:
const sortable = new Sortable(document.querySelectorAll('.container'), {
draggable: '.item',
mirror: {
constrainDimensions: true,
appendTo: document.body, // зеркальный элемент добавляется в body
xAxis: true,
yAxis: true,
},
});
appendTo – определяет, куда будет помещён зеркальный
элемент.xAxis и yAxis – ограничивают движение по
конкретным осям.constrainDimensions – сохраняет ширину и высоту
оригинального элемента.Sortable поддерживает работу с несколькими контейнерами одновременно. Это позволяет реализовать функциональность перетаскивания элементов между списками:
const containers = document.querySelectorAll('.container');
const sortable = new Sortable(containers, {
draggable: '.item',
mirror: { constrainDimensions: true },
});
Все контейнеры теперь связаны и элементы можно перемещать между ними.
Для обработки таких действий полезно использовать событие
sortable:sorted, где можно определить исходный и новый
контейнер:
sortable.on('sortable:sorted', (event) => {
const { oldIndex, newIndex, source, over } = event.data;
console.log(`Элемент перемещён из контейнера`, source, `в контейнер`, over);
});
Если список элементов меняется динамически (например, элементы добавляются через JavaScript), необходимо уведомить Sortable о новых элементах:
sortable.destroy(); // удаляет текущий экземпляр
sortable = new Sortable(document.querySelectorAll('.container'), {
draggable: '.item',
});
Или использовать sortable.addDraggables для добавления
новых элементов без полной инициализации:
const newItems = document.querySelectorAll('.container .new-item');
sortable.addDraggables(newItems);
Для более плавного и наглядного перетаскивания можно использовать CSS-анимации и классы, добавляемые Sortable:
.draggable-item {
transition: transform 0.2s ease;
}
.dragging {
opacity: 0.8;
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
Sortable автоматически добавляет класс dragging к
элементу, за которым следует курсор, и обновляет его положение с помощью
transform, что позволяет легко применять визуальные эффекты.
Sortable поддерживает ограничение перемещения элементов через события и пользовательскую логику:
sortable.on('sortable:sort', (event) => {
const { dragEvent } = event.data;
if (dragEvent.source.dataset.fixed) {
dragEvent.cancel(); // отменяет перемещение для фиксированного элемента
}
});
Это удобно для реализации списков с элементами, которые нельзя перемещать или перемещать только в определённых условиях.
Эта структура и возможности Sortable позволяют строить сложные интерактивные списки с полной кастомизацией поведения, визуальной индикацией, динамическим обновлением и поддержкой нескольких контейнеров, создавая гибкие интерфейсы drag-and-drop на JavaScript.