Получение нового порядка элементов

Библиотека 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 каждого элемента используется для отслеживания идентификаторов. Такой подход позволяет синхронизировать порядок с базой данных или интерфейсом.

Методы получения порядка элементов

  1. Через DOM После завершения сортировки порядок элементов можно получить напрямую из родительского контейнера, используя children:
const currentOrder = Array.from(container.children).map(item => item.id);

Этот метод прост и надёжен, особенно если каждый элемент имеет уникальный идентификатор.

  1. Через массив элементов Draggable Draggable хранит массив 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 обеспечивает простую и стабильную синхронизацию между фронтендом и бекендом.

Отслеживание изменения порядка без завершения drag

Иногда требуется получить текущий порядок элементов на лету во время перемещения. Для этого применяется событие 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 и правильного использования идентификаторов элементов. Такой подход обеспечивает стабильную синхронизацию интерфейса и данных, делает списки интерактивными и адаптируемыми для сложных пользовательских сценариев.