SortableJS — это современная и высокопроизводительная библиотека для организации перетаскивания элементов в списках. Она позволяет создавать интерфейсы с динамическим изменением порядка элементов без сложного DOM-манипулирования. Основой работы является инициализация Sortable на контейнере с элементами, за которыми требуется наблюдать.
import Sortable from 'sortablejs';
const list = document.getElementById('sortable-list');
const sortable = new Sortable(list, {
animation: 150,
ghostClass: 'sortable-ghost'
});
animation — задаёт плавность
перемещения элементов в миллисекундах.ghostClass — класс, который
применяется к перемещаемому элементу для визуального эффекта.Множественное выделение элементов позволяет перетаскивать одновременно несколько элементов, а не один. Это особенно важно для интерфейсов с таблицами, галереями или списками задач.
SortableJS из коробки не поддерживает множественный drag’n’drop
напрямую, поэтому используется комбинация выделения элементов и передачи
их в событие onStart.
let selectedItems = new Set();
list.addEventListener('click', (e) => {
const item = e.target.closest('.sortable-item');
if (!item) return;
if (e.ctrlKey || e.metaKey) {
item.classList.toggle('selected');
if (item.classList.contains('selected')) {
selectedItems.add(item);
} else {
selectedItems.delete(item);
}
} else {
selectedItems.forEach(i => i.classList.remove('selected'));
selectedItems.clear();
item.classList.add('selected');
selectedItems.add(item);
}
});
ctrlKey / metaKey —
проверка зажатой клавиши для добавления в выделение без снятия
предыдущего.selectedItems — структура для хранения
выбранных элементов.Для перетаскивания одновременно нескольких элементов используется
обработка события onStart. Перетаскиваемый элемент должен
быть первым в наборе выделенных элементов.
const sortable = new Sortable(list, {
animation: 150,
multiDrag: true,
selectedClass: 'selected',
onStart(evt) {
if (!evt.item.classList.contains('selected')) {
selectedItems.forEach(i => i.classList.remove('selected'));
selectedItems.clear();
evt.item.classList.add('selected');
selectedItems.add(evt.item);
}
},
onEnd(evt) {
selectedItems.forEach(i => i.classList.remove('selected'));
selectedItems.clear();
}
});
multiDrag — флаг для включения режима
перетаскивания нескольких элементов.selectedClass — CSS-класс для
выделенных элементов.onStart и
onEnd — события начала и конца
перетаскивания, где можно управлять выделением.SortableJS поддерживает перенос элементов между различными контейнерами. Для множественного выделения это требует проверки каждого элемента на принадлежность к текущему контейнеру и синхронизации позиции после вставки.
const containers = document.querySelectorAll('.sortable-container');
containers.forEach(container => {
new Sortable(container, {
group: 'shared',
animation: 150,
multiDrag: true,
selectedClass: 'selected',
onAdd(evt) {
selectedItems.forEach(item => {
if (!evt.to.contains(item)) {
evt.to.appendChild(item);
}
});
selectedItems.clear();
}
});
});
group — объединяет контейнеры, между
которыми возможен обмен элементами.onAdd — событие добавления элемента в
другой контейнер, где необходимо корректно вставить все выделенные
элементы.Для удобства пользователя важно визуально обозначать выбранные элементы и их состояние при перетаскивании.
.sortable-item.selected {
background-color: rgba(0, 123, 255, 0.3);
border: 1px solid #007bff;
}
.sortable-ghost {
opacity: 0.5;
transform: scale(1.05);
}
.selected — выделение активных
элементов..sortable-ghost — эффект «призрака»
для перетаскиваемого элемента.SortableJS позволяет комбинировать множественное выделение с другими функциональностями:
filter.onMove: проверка допустимости
перемещения элементов перед фактическим переносом.const sortable = new Sortable(list, {
multiDrag: true,
selectedClass: 'selected',
filter: '.disabled',
onMove(evt) {
return !evt.related.classList.contains('disabled');
}
});
filter — элементы с этим селектором
нельзя перетаскивать.onMove — проверка на возможность
перемещения перед реорганизацией DOM.Множественное выделение в SortableJS сочетает удобство пользовательского интерфейса с гибкой настройкой поведения перетаскивания, обеспечивая динамичное взаимодействие с большими списками и коллекциями элементов.