SortableJS — это мощная библиотека для реализации перетаскивания
элементов списка (drag-and-drop) в веб-приложениях. Она предоставляет
высокую гибкость и поддерживает работу как с простыми списками, так и с
вложенными структурами. Основной объект для инициализации —
Sortable, который связывается с DOM-элементом
контейнера.
import Sortable from 'sortablejs';
const list = document.getElementById('myList');
const sortable = new Sortable(list, {
animation: 150,
handle: '.handle',
ghostClass: 'sortable-ghost',
});
Ключевые опции:
animation — скорость анимации перемещения элементов в
миллисекундах.handle — селектор, задающий область
перетаскивания.ghostClass — класс, применяемый к элементу, который
временно отображается во время перемещения.При работе с тысячами элементов стандартная инициализация SortableJS может вызывать значительные задержки. Основные методы оптимизации включают:
Вместо привязки событий к каждому элементу рекомендуется использовать
делегирование через контейнер. SortableJS изначально использует
делегирование, но при кастомизации handle или
filter нужно избегать тяжелых операций на каждом
элементе.
const sortable = new Sortable(list, {
handle: '.handle',
filter: '.disabled',
onMove: (evt) => {
return !evt.related.classList.contains('disabled');
}
});
onMove вызывается на каждом перемещении, поэтому лучше
минимизировать в нём вычисления.
Для списков с тысячами элементов имеет смысл использовать виртуализацию, когда в DOM присутствует только видимая часть элементов. SortableJS совместим с виртуализированными списками, но важно правильно синхронизировать индексы:
// Использование виртуализатора (например, виртуального скролла)
const visibleItems = virtualScroll.getVisibleItems();
const sortable = new Sortable(container, {
draggable: '.item',
animation: 100
});
В этом случае библиотека перетаскивает только реально отображаемые элементы, что существенно снижает нагрузку на браузер.
Опция draggable позволяет выбрать только подмножество
элементов, которые могут быть перемещены. Это сокращает количество
обработчиков событий и ускоряет работу:
const sortable = new Sortable(list, {
draggable: '.draggable-item',
});
Каждое изменение позиции элемента приводит к перерисовке.
Рекомендуется использовать классы для стилизации вместо частого
изменения inline-стилей и минимизировать вызовы appendChild
и insertBefore.
SortableJS предоставляет богатый набор событий, позволяющих контролировать поведение при перетаскивании:
onStart — срабатывает при начале перетаскивания.onEnd — срабатывает после завершения перемещения.onAdd, onRemove, onUpdate —
вызываются при изменении списка, добавлении или удалении элемента.onSort — срабатывает каждый раз при изменении
порядка.Для больших списков важно избегать сложных операций внутри этих
обработчиков. Например, обновление интерфейса или обращение к серверу
лучше делать асинхронно или через
requestAnimationFrame.
sortable.option("onEnd", function(evt) {
requestAnimationFrame(() => {
updateOrderInDatabase(evt.oldIndex, evt.newIndex);
});
});
SortableJS поддерживает возможность объединения нескольких списков в
одну группу. Опция group управляет, какие списки могут
обмениваться элементами:
const sortable1 = new Sortable(list1, {
group: 'shared',
animation: 150,
});
const sortable2 = new Sortable(list2, {
group: 'shared',
animation: 150,
});
Для оптимизации рекомендуется:
pull и put).Ghost и clone элементы
ghostClass — для временного отображения элемента при
перетаскивании.setData и onClone — для создания копий
элементов без полного пересоздания DOM.const sortable = new Sortable(list, {
animation: 150,
ghostClass: 'ghost',
onClone: (evt) => {
evt.clone.style.background = '#f0f0f0';
}
});
Это помогает снизить нагрузку на браузер при больших списках, так как не происходит лишних манипуляций с DOM.
onMove и onSort должны выполнять
только легкие вычисления.Эти подходы позволяют поддерживать плавное перетаскивание и отзывчивость интерфейса даже при работе с десятками тысяч элементов.