SortableJS — это мощная библиотека на JavaScript, предназначенная для реализации перетаскивания элементов списка с минимальными усилиями. Она широко используется для создания интерактивных интерфейсов, где требуется возможность менять порядок элементов или строить сложные иерархические структуры.
Для работы с SortableJS необходимо подключить библиотеку к проекту. Можно использовать CDN:
<script src="https://cdn.jsdelivr.net/npm/sortablejs@1.15.0/Sortable.min.js"></script>
Или установить через npm:
npm install sortablejs
Инициализация базового списка выглядит следующим образом:
const el = document.getElementById('list');
const sortable = new Sortable(el, {
animation: 150,
ghostClass: 'sortable-ghost'
});
animation — длительность анимации при перемещении
элементов.ghostClass — CSS-класс, применяемый к элементу во время
перетаскивания.Для реализации древовидных структур используется концепция вложенных
списков. Каждый элемент, который может содержать подсписок, оформляется
как контейнер с вложенным <ul> или
<ol>.
<ul id="tree">
<li>
Пункт 1
<ul>
<li>Подпункт 1.1</li>
<li>Подпункт 1.2</li>
</ul>
</li>
<li>Пункт 2</li>
</ul>
Каждый уровень иерархии можно инициализировать отдельным экземпляром SortableJS:
function makeSortable(el) {
new Sortable(el, {
group: 'nested',
animation: 150,
fallbackOnBody: true,
swapThreshold: 0.65,
onAdd: function (evt) {
console.log('Элемент добавлен:', evt.item);
}
});
Array.from(el.children).forEach(child => {
const nested = child.querySelector('ul');
if (nested) {
makeSortable(nested);
}
});
}
makeSortable(document.getElementById('tree'));
group: 'nested' — позволяет элементам из разных списков
одной группы быть перетаскиваемыми между собой.fallbackOnBody — временно переносит элемент в
<body> при перетаскивании, чтобы избежать проблем с
overflow контейнеров.swapThreshold — порог срабатывания при обмене
элементов.SortableJS предоставляет широкий набор событий для управления действиями пользователя:
onStart — срабатывает при начале перетаскивания.onEnd — после завершения перетаскивания.onAdd — элемент добавлен в новый список.onUpdate — порядок элементов изменён в пределах одного
списка.onRemove — элемент удалён из списка.Пример обработки событий для обновления данных после перетаскивания:
new Sortable(listElement, {
group: 'nested',
onEnd: function (evt) {
const updatedOrder = [];
listElement.querySelectorAll('li').forEach(li => {
updatedOrder.push(li.textContent.trim());
});
console.log('Обновлённый порядок:', updatedOrder);
}
});
onMove:onMove: function (evt, originalEvent) {
const target = evt.related;
let depth = 0;
let node = target;
while (node && node !== document.body) {
if (node.tagName === 'UL') depth++;
node = node.parentNode;
}
return depth <= 3; // Максимальная глубина 3
}
Стилизация элементов — класс
ghostClass позволяет визуально отделять перетаскиваемый
элемент. Класс chosenClass выделяет выбранный элемент до
начала перемещения.
Сериализация дерева — после перестановки элементов часто требуется сохранить иерархию. Для этого удобно использовать рекурсивную функцию:
function serializeTree(ul) {
return Array.from(ul.children).map(li => {
const nested = li.querySelector('ul');
return {
text: li.firstChild.textContent.trim(),
children: nested ? serializeTree(nested) : []
};
});
}
const treeData = serializeTree(document.getElementById('tree'));
console.log(treeData);
SortableJS легко интегрируется с React, Vue и Angular через специализированные обёртки или кастомные компоненты. Основная концепция работы с DOM остаётся прежней: создаётся контейнер для элементов, к которому подключается Sortable, и события используются для синхронизации состояния с внутренними структурами данных.
Использование SortableJS для древовидных структур обеспечивает гибкость и контроль над сложными интерфейсами, позволяя управлять вложенностью, отслеживать изменения и сохранять иерархические данные в удобной форме для дальнейшей обработки.