Применение в интерфейсах

SortableJS — это лёгкая и мощная библиотека для реализации перетаскивания элементов (drag-and-drop) в веб-интерфейсах. Она работает с обычными HTML-списками (<ul>, <ol>) и блоками (<div>), обеспечивая высокую производительность и широкую кастомизацию поведения.

Подключение библиотеки производится через CDN или установкой через npm/yarn:

<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>

или

npm install sortablejs

Инициализация происходит на выбранном контейнере:

const list = document.getElementById('items');
const sortable = new Sortable(list, {
    animation: 150,
    ghostClass: 'sortable-ghost'
});

Ключевые параметры:

  • animation — плавность анимации при перемещении элементов.
  • ghostClass — CSS-класс для визуального эффекта «тени» перемещаемого элемента.
  • handle — позволяет ограничить область захвата элемента для перетаскивания.
  • draggable — CSS-селектор для элементов, которые можно перемещать.

Основные методы и события

SortableJS предоставляет API для управления списком и обработки действий пользователя.

Методы:

  • toArray() — возвращает массив идентификаторов элементов.
  • sort(orderArray) — сортирует элементы согласно массиву идентификаторов.
  • destroy() — удаляет функциональность сортировки с элемента.
  • option(name, value) — изменяет или получает значение опции на лету.

События:

  • onStart(evt) — при начале перетаскивания.
  • onEnd(evt) — при завершении перетаскивания.
  • onAdd(evt) — элемент добавлен из другого списка.
  • onUpdate(evt) — элемент перемещён внутри текущего списка.
  • onRemove(evt) — элемент удалён в другой список.
  • onSort(evt) — любое изменение порядка элементов.

Пример обработки события onEnd:

sortable.option('onEnd', function (evt) {
    console.log('Элемент перемещён', evt.item);
});

Связка нескольких списков

SortableJS поддерживает связанные списки, позволяя перемещать элементы между ними. Для этого используется опция group:

const groupOptions = {
    name: 'shared',
    pull: true,
    put: true
};

new Sortable(document.getElementById('list1'), { group: groupOptions });
new Sortable(document.getElementById('list2'), { group: groupOptions });

Параметры pull и put регулируют возможность перемещения элементов из списка и в список соответственно.


Работа с динамическими элементами

Если элементы добавляются в DOM после инициализации SortableJS, необходимо использовать метод Sortable.create() на новом контейнере. Для уже существующих контейнеров можно обновить данные с помощью:

sortable.save(); // сохранить текущий порядок
sortable.sort(orderArray); // применить новый порядок

Настройка внешнего вида и UX

Ghost-эффект: выделяет перетаскиваемый элемент для удобства визуального восприятия. CSS:

.sortable-ghost {
    opacity: 0.4;
    background-color: #ccc;
}

Handle: позволяет ограничить область захвата элемента, предотвращая случайное перемещение:

new Sortable(list, {
    handle: '.drag-handle'
});

Filter: запрещает перетаскивание определённых элементов:

new Sortable(list, {
    filter: '.no-drag',
    onFilter: function (evt) {
        console.log('Элемент не подлежит перемещению', evt.item);
    }
});

Сортировка с сохранением состояния

Часто требуется сохранять порядок элементов на сервере. Для этого используется toArray() и отправка данных через AJAX:

sortable.option('onEnd', function () {
    const order = sortable.toArray();
    fetch('/save-order', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ order })
    });
});

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


Интеграция с фреймворками

SortableJS легко интегрируется с React, Vue и Angular благодаря чистому API. В этих случаях создаётся обёртка компонента:

Пример для Vue 3:

<template>
  <ul ref="list">
    <li v-for="item in items" :key="item.id">{{ item.name }}</li>
  </ul>
</template>

<script>
import Sortable from 'sortablejs';

export default {
  props: ['items'],
  mounted() {
    Sortable.create(this.$refs.list, {
      animation: 150,
      onEnd: (evt) => {
        const movedItem = this.items.splice(evt.oldIndex, 1)[0];
        this.items.splice(evt.newIndex, 0, movedItem);
      }
    });
  }
}
</script>

Таким образом сохраняется состояние реактивного массива при перетаскивании.


Расширенные возможности

  • Swap: можно реализовать обмен местами элементов без сдвига других.
  • Multi-drag: поддержка множественного выбора элементов.
  • Plugins: добавление функций через плагины SortableJS (например, auto-scroll или handle-cloning).

Настройка multi-drag:

Sortable.create(list, {
    multiDrag: true,
    selectedClass: 'selected',
    onEnd(evt) {
        console.log('Выбранные элементы:', evt.items);
    }
});

Эта функциональность делает SortableJS идеальным инструментом для сложных интерфейсных задач, таких как панели инструментов, списки задач или динамические таблицы.