SortableJS — это мощная библиотека для реализации перетаскивания элементов в веб-приложениях на JavaScript. Она позволяет создавать интерактивные списки с возможностью сортировки, изменять порядок элементов динамически и интегрироваться с другими интерфейсными компонентами.
Создание базового списка начинается с инициализации Sortable на выбранном контейнере:
import Sortable from 'sortablejs';
const list = document.getElementById('sortable-list');
const sortable = new Sortable(list, {
animation: 150,
ghostClass: 'sortable-ghost',
chosenClass: 'sortable-chosen',
dragClass: 'sortable-drag'
});
Ключевые опции:
animation — задаёт плавность анимации при перемещении
элементов.ghostClass — класс, применяемый к элементу-заглушке во
время перетаскивания.chosenClass — класс выбранного элемента.dragClass — класс, применяемый к элементу в момент
активного перетаскивания.SortableJS предоставляет широкий набор событий, позволяющих контролировать процесс сортировки и реагировать на действия пользователя.
Основные события:
onStart — вызывается при начале перетаскивания
элемента.onEnd — срабатывает после завершения перемещения
элемента.onAdd — используется, когда элемент добавлен из другого
списка.onUpdate — вызывается, если порядок элементов внутри
списка изменён.onRemove — срабатывает при удалении элемента из
списка.Пример использования событий:
sortable.on('onEnd', function (evt) {
console.log(`Элемент ${evt.item.textContent} перемещён с позиции ${evt.oldIndex} на ${evt.newIndex}`);
});
SortableJS поддерживает работу с несколькими списками, позволяя
перемещать элементы между ними с помощью опции group. Это
особенно полезно при создании досок задач, таблиц или
kanban-интерфейсов.
const groupOptions = {
group: 'shared',
animation: 150,
pull: true,
put: true
};
Sortable.create(document.getElementById('list1'), groupOptions);
Sortable.create(document.getElementById('list2'), groupOptions);
Пояснения по опциям группы:
group — имя группы списков, элементы которой можно
перемещать между контейнерами.pull — разрешает выносить элементы из списка.put — разрешает вставку элементов из других
списков.SortableJS позволяет программно добавлять и удалять элементы из списка, а также изменять их порядок.
Добавление элемента:
const newItem = document.createElement('li');
newItem.textContent = 'Новый элемент';
list.appendChild(newItem);
sortable.sort([...list.children].map(el => el));
Удаление элемента:
list.removeChild(list.children[2]);
Изменение порядка элементов через метод
sort:
sortable.sort([2, 0, 1]); // меняет порядок элементов на заданный массив индексов
Можно запрещать перетаскивание определённых элементов с помощью опций
filter и preventOnFilter:
Sortable.create(list, {
filter: '.no-drag',
preventOnFilter: false,
animation: 150
});
filter — селектор элементов, для которых перетаскивание
запрещено.preventOnFilter — управляет предотвращением
стандартного поведения браузера при фильтрации.Для удобства пользователя важно настроить визуальные эффекты:
ghostClass)
показывает, как элемент будет перемещён.chosenClass) выделяет активный элемент.animation) делает
перемещение элементов естественным..sortable-ghost {
opacity: 0.4;
border: 1px dashed #ccc;
}
.sortable-chosen {
background-color: #f0f0f0;
}
.sortable-drag {
cursor: grabbing;
}
SortableJS легко интегрируется с сохранением состояния на сервере. После изменения порядка элементов можно отправить обновлённый порядок в базу данных:
sortable.on('onEnd', function (evt) {
const order = [...list.children].map(el => el.dataset.id);
fetch('/update-order', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({order})
});
});
Это обеспечивает синхронизацию интерфейса с серверной логикой и позволяет реализовать динамические списки с постоянным порядком элементов.
SortableJS поддерживает вложенные списки (nested lists), что позволяет создавать сложные структуры:
Sortable.create(document.getElementById('parent-list'), {
group: 'nested',
animation: 150,
fallbackOnBody: true,
swapThreshold: 0.65
});
fallbackOnBody — временно переносит элемент на тело
документа при перетаскивании, чтобы избежать проблем с overflow.swapThreshold — чувствительность к обмену элементов при
пересечении.Для динамических интерфейсов важно сохранять порядок элементов при обновлении страницы. Это реализуется через хранение массива идентификаторов элементов и повторную сортировку при загрузке:
const savedOrder = JSON.parse(localStorage.getItem('listOrder')) || [];
if (savedOrder.length) {
sortable.sort(savedOrder);
}
sortable.on('onEnd', function () {
const order = [...list.children].map(el => el.dataset.id);
localStorage.setItem('listOrder', JSON.stringify(order));
});
Такой подход обеспечивает постоянство пользовательских изменений и удобство работы с динамическими данными.
animation с небольшим значением
(например, 150–200 мс) улучшает отзывчивость интерфейса.filter уменьшает количество
ненужных обработчиков.fallbackOnBody только при
необходимости, чтобы избежать лишнего рендеринга.SortableJS сочетает гибкость и простоту, предоставляя полный контроль над интерактивными списками. С его помощью можно строить сложные интерфейсы с динамическими данными, поддержкой нескольких списков, анимацией и сохранением состояния, обеспечивая при этом высокую производительность и удобство пользователя.