SortableJS — это мощная библиотека для создания интерактивных списков с поддержкой перетаскивания элементов (drag-and-drop). Одним из ключевых аспектов работы с такими списками является управление состоянием элементов: сохранение текущего порядка, синхронизация с данными приложения и обработка событий, связанных с изменениями.
Создание сортируемого списка начинается с вызова конструктора
Sortable и передачи ему DOM-элемента списка:
import Sortable from 'sortablejs';
const listElement = document.getElementById('my-list');
const sortable = new Sortable(listElement, {
animation: 150,
ghostClass: 'sortable-ghost'
});
Ключевые параметры:
animation — скорость анимации при перетаскивании
элементов в миллисекундах.ghostClass — CSS-класс, применяемый к элементу во время
перетаскивания.draggable — селектор дочерних элементов, которые можно
перетаскивать.handle — селектор элемента внутри элемента списка,
который служит “ручкой” для перетаскивания.Базовое состояние списка хранится в DOM-порядке элементов. Для
синхронизации с данными приложения рекомендуется использовать методы
toArray() и sort().
const order = sortable.toArray(); // Получение текущего порядка элементов по их ID
Эти ID назначаются с помощью атрибута data-id для
каждого элемента списка. Это позволяет сохранить уникальную
идентификацию элементов при изменении порядка.
SortableJS предоставляет систему событий для управления состоянием и синхронизации с приложением.
Основные события:
onStart — срабатывает в момент начала
перетаскивания.onEnd — срабатывает после завершения перетаскивания,
даже если элемент вернулся на исходное место.onUpdate — срабатывает, когда элемент был перемещен в
пределах того же списка.onAdd — срабатывает, когда элемент добавлен из другого
списка.onRemove — срабатывает, когда элемент удален в пользу
другого списка.onSort — срабатывает при любом изменении порядка
элементов в списке.Пример отслеживания и сохранения нового порядка:
sortable.option("onEnd", function (evt) {
const newOrder = sortable.toArray();
console.log("Новый порядок элементов:", newOrder);
// Можно обновить состояние приложения или отправить данные на сервер
});
Использование событий onAdd и onRemove
позволяет поддерживать состояние нескольких связанных
списков, обеспечивая точное отражение изменений в данных.
Для большинства приложений важно, чтобы изменения в DOM отражались в структуре данных. Обычно это делается через массив объектов, где каждый объект соответствует элементу списка:
let items = [
{ id: 1, name: 'Элемент 1' },
{ id: 2, name: 'Элемент 2' },
{ id: 3, name: 'Элемент 3' }
];
Для синхронизации после перетаскивания применяется метод
toArray():
sortable.option("onEnd", function () {
const order = sortable.toArray(); // ['2', '1', '3']
items.sort((a, b) => order.indexOf(String(a.id)) - order.indexOf(String(b.id)));
});
Таким образом, порядок элементов в массиве items всегда
соответствует текущему визуальному порядку в DOM.
SortableJS поддерживает перетаскивание элементов между
списками через параметр group. Группы могут быть
настроены с опциями pull и put для контроля
направления перемещения:
new Sortable(listA, {
group: {
name: 'shared',
pull: 'clone',
put: false
}
});
new Sortable(listB, {
group: 'shared'
});
pull — определяет, можно ли вытаскивать элементы из
этого списка.put — определяет, можно ли добавлять элементы в этот
список.Использование событий onAdd и onRemove
позволяет корректно обновлять состояние обоих списков после перемещения
элемента.
Для долговременного хранения состояния списка часто используют локальное хранилище (localStorage) или серверные запросы. Пример сохранения и восстановления порядка:
// Сохранение
sortable.option("onEnd", function () {
localStorage.setItem('listOrder', JSON.stringify(sortable.toArray()));
});
// Восстановление
const savedOrder = JSON.parse(localStorage.getItem('listOrder'));
if (savedOrder) {
savedOrder.forEach(id => {
const element = document.querySelector(`[data-id='${id}']`);
if (element) listElement.appendChild(element);
});
}
Это гарантирует, что после перезагрузки страницы порядок элементов будет соответствовать последнему сохраненному состоянию.
SortableJS позволяет блокировать отдельные элементы или ограничивать перетаскивание с помощью CSS-классов и параметров:
draggable — ограничивает элементы, которые можно
перетаскивать.filter — предотвращает перетаскивание элементов с
заданным селектором.disabled — полная блокировка списка.Пример фильтрации:
new Sortable(listElement, {
filter: '.no-drag',
onMove: function (evt) {
return !evt.related.classList.contains('no-drag');
}
});
Элементы с классом no-drag не будут участвовать в
перетаскивании, сохраняя неизменное состояние.
SortableJS предоставляет методы для динамического изменения опций и состояния после инициализации:
sortable.option('disabled', true) — временно блокирует
перетаскивание.sortable.sort(newOrder) — программно изменяет порядок
элементов.sortable.destroy() — полностью удаляет функциональность
сортировки, оставляя DOM нетронутым.Программное изменение порядка через sort():
sortable.sort(['3', '1', '2']); // Устанавливает новый порядок по ID элементов
Этот подход удобен для синхронизации с внешними источниками данных, API или событиями приложения.
data-id и toArray()
обеспечивает безопасную синхронизацию с массивами данных.onEnd, onUpdate,
onAdd, onRemove — основной инструмент
отслеживания изменений.sort(), option() и
destroy() позволяют динамически управлять поведением и
состоянием списка.Эти механизмы делают SortableJS гибким инструментом для управления состоянием интерактивных списков и интеграции их в любые приложения на JavaScript.