Одноуровневая сортировка

Для начала необходимо подключить библиотеку Shopify Draggable. Она распространяется как через npm, так и через CDN. Для npm используется команда:

npm install @shopify/draggable

После установки можно импортировать необходимые модули в проект:

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

Если используется подключение через CDN, достаточно добавить в HTML:

<script src="https://cdn.jsdelivr.net/npm/@shopify/draggable@1.0.0-beta.12/lib/draggable.bundle.js"></script>

Создание контейнера и элементов

Одноуровневая сортировка работает на контейнере с набором элементов. Структура HTML должна быть простой:

<ul id="sortable-list">
  <li class="draggable-item">Элемент 1</li>
  <li class="draggable-item">Элемент 2</li>
  <li class="draggable-item">Элемент 3</li>
  <li class="draggable-item">Элемент 4</li>
</ul>
  • Контейнер <ul> или <div> может содержать любое количество элементов.
  • Каждый элемент должен иметь общий класс для селектора Draggable.

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

Создание экземпляра Draggable для одноуровневой сортировки:

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

Пояснения параметров:

  • draggable — CSS-селектор элементов, которые можно перетаскивать.
  • mirror.constrainDimensions — сохраняет размеры элемента при перетаскивании.
  • Другие опции: delay (задержка перед захватом), handle (только по определённому элементу внутри draggable).

Работа с событиями

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

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

sortable.on('drag:move', (event) => {
  console.log('Движение:', event.source);
});

sortable.on('drag:stop', (event) => {
  console.log('Конец перетаскивания:', event.source);
});

sortable.on('sortable:stop', (event) => {
  console.log('Новая позиция элемента:', event.newIndex);
});

Ключевые моменты:

  • drag:start — срабатывает при начале перетаскивания.
  • drag:move — срабатывает при перемещении мыши.
  • drag:stop — срабатывает при отпускании элемента.
  • sortable:stop — срабатывает после завершения сортировки, позволяет узнать новый порядок.

Настройка визуальных эффектов

Draggable позволяет кастомизировать отображение «зеркала» перетаскиваемого элемента:

const sortable = new Draggable(document.querySelectorAll('#sortable-list'), {
  draggable: '.draggable-item',
  classes: {
    mirror: 'custom-mirror',
    chosen: 'custom-chosen',
    dragging: 'custom-dragging'
  }
});
  • mirror — класс для временного элемента, который следует за курсором.
  • chosen — класс для выделенного элемента.
  • dragging — класс для элемента, который перемещается.

CSS для этих классов может включать прозрачность, тени, анимацию:

.custom-mirror {
  opacity: 0.7;
  box-shadow: 0 5px 15px rgba(0,0,0,0.2);
}

.custom-chosen {
  background-color: #f0f0f0;
}

.custom-dragging {
  opacity: 0.9;
}

Ограничение области перетаскивания

Для предотвращения выхода элементов за пределы контейнера можно использовать опцию containers:

const sortable = new Draggable(document.querySelectorAll('#sortable-list'), {
  draggable: '.draggable-item',
  containers: [document.querySelector('#sortable-list')]
});

Элементы будут перемещаться только внутри указанных контейнеров.

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

После завершения сортировки часто необходимо узнать новый порядок элементов:

sortable.on('sortable:stop', () => {
  const items = document.querySelectorAll('#sortable-list .draggable-item');
  const order = Array.from(items).map(item => item.textContent);
  console.log('Текущий порядок:', order);
});

Такой подход позволяет интегрировать сортировку с сервером или локальным хранилищем.

Добавление и удаление элементов динамически

Draggable поддерживает динамическое добавление и удаление элементов:

// Добавление нового элемента
const newItem = document.createElement('li');
newItem.classList.add('draggable-item');
newItem.textContent = 'Новый элемент';
document.querySelector('#sortable-list').appendChild(newItem);

// Обновление Draggable
sortable.destroy();
sortable.init();

Удаление элементов также требует пересоздания экземпляра или обновления DOM, чтобы Draggable корректно отслеживал новые элементы.

Настройка ограничения по оси

Для одноуровневой сортировки полезно ограничить движение по оси Y или X:

const sortable = new Draggable(document.querySelectorAll('#sortable-list'), {
  draggable: '.draggable-item',
  axis: 'y'
});
  • axis: 'y' — вертикальная сортировка.
  • axis: 'x' — горизонтальная сортировка.

Это предотвращает случайное смещение элементов в нежелательном направлении.

Интеграция с данными

Новые индексы элементов можно отправлять на сервер после сортировки:

sortable.on('sortable:stop', (event) => {
  const updatedOrder = Array.from(document.querySelectorAll('#sortable-list .draggable-item'))
                            .map(el => el.dataset.id);
  fetch('/update-order', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ order: updatedOrder })
  });
});

Использование data-attributes обеспечивает надежную привязку элементов к их идентификаторам.


Эта структура позволяет создавать гибкие одноуровневые сортировки с Draggable, полностью управляемые через JavaScript и CSS, с возможностью динамического изменения контента и интеграции с внешними данными.