Библиотека Shopify Draggable предоставляет мощный и гибкий инструмент для реализации перетаскивания элементов на веб-странице. Один из ключевых аспектов интерактивных списков — возможность определить новый порядок элементов после завершения операции drag-and-drop.
Для отслеживания изменений порядка элементов используются события, встроенные в Draggable:
sortable:stop — срабатывает после
того, как пользователь закончил перетаскивать элемент. В этот момент DOM
уже обновлён, и можно безопасно получать актуальный порядок
элементов.sortable:sort — срабатывает во время
сортировки, может быть полезно для реализации визуальных подсказок, но
для получения окончательного порядка лучше использовать
sortable:stop.Пример регистрации события:
const container = document.querySelector('.draggable-container');
const draggable = new Draggable.Sortable(container, {
draggable: '.draggable-item'
});
draggable.on('sortable:stop', (event) => {
console.log('Элемент перемещён:', event.data.dragEvent.source);
const currentOrder = Array.from(container.children).map(item => item.dataset.id);
console.log('Текущий порядок элементов:', currentOrder);
});
В этом примере dataset.id каждого элемента используется
для отслеживания идентификаторов. Такой подход позволяет
синхронизировать порядок с базой данных или интерфейсом.
children:const currentOrder = Array.from(container.children).map(item => item.id);
Этот метод прост и надёжен, особенно если каждый элемент имеет уникальный идентификатор.
draggable.getDraggables(), который содержит все
элементы:const draggables = draggable.getDraggables();
const currentOrder = draggables.map(item => item.dataset.id);
Этот способ позволяет получить список элементов в том порядке, в котором они отслеживаются библиотекой, что иногда удобнее при сложных конфигурациях.
После получения актуального порядка элементов часто возникает необходимость сохранить его на сервере или в локальном хранилище. Простейший пример с использованием Fetch API:
draggable.on('sortable:stop', () => {
const currentOrder = Array.from(container.children).map(item => item.dataset.id);
fetch('/update-order', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ order: currentOrder })
})
.then(response => response.json())
.then(data => console.log('Порядок сохранён:', data))
.catch(error => console.error('Ошибка при сохранении:', error));
});
Использование dataset.id обеспечивает простую и
стабильную синхронизацию между фронтендом и бекендом.
Иногда требуется получить текущий порядок элементов на
лету во время перемещения. Для этого применяется событие
sortable:sort:
draggable.on('sortable:sort', () => {
const liveOrder = Array.from(container.children).map(item => item.dataset.id);
console.log('Текущий порядок на лету:', liveOrder);
});
Это позволяет создавать динамические интерфейсы с мгновенной визуальной обратной связью.
Draggable поддерживает сортировку между несколькими
контейнерами через опцию containers. Получение
порядка в этом случае требует обхода каждого контейнера:
const containers = document.querySelectorAll('.draggable-container');
draggable.on('sortable:stop', () => {
containers.forEach(container => {
const order = Array.from(container.children).map(item => item.dataset.id);
console.log(`Порядок в контейнере ${container.id}:`, order);
});
});
Каждый контейнер отслеживается отдельно, что обеспечивает точное понимание положения элементов в сложных интерфейсах.
sortable:sort, лучше обрабатывать только
sortable:stop.DocumentFragment для минимизации перерисовок DOM.data-* атрибуты с JSON-данными,
чтобы хранить дополнительную информацию об элементах и легко
восстанавливать порядок.Получение нового порядка элементов в Shopify Draggable — это сочетание отслеживания событий, работы с DOM и правильного использования идентификаторов элементов. Такой подход обеспечивает стабильную синхронизацию интерфейса и данных, делает списки интерактивными и адаптируемыми для сложных пользовательских сценариев.