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); // применить новый порядок
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>
Таким образом сохраняется состояние реактивного массива при перетаскивании.
Настройка multi-drag:
Sortable.create(list, {
multiDrag: true,
selectedClass: 'selected',
onEnd(evt) {
console.log('Выбранные элементы:', evt.items);
}
});
Эта функциональность делает SortableJS идеальным инструментом для сложных интерфейсных задач, таких как панели инструментов, списки задач или динамические таблицы.