SortableJS — это библиотека для реализации перетаскивания элементов в списках с поддержкой Drag and Drop. Для работы с ней достаточно подключить скрипт через CDN или установить пакет через npm/yarn.
Через CDN:
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>
Через npm:
npm install sortablejs
После установки библиотека доступна для использования в проекте:
import Sortable from 'sortablejs';
Для создания сортируемого списка достаточно передать контейнер элементов в конструктор Sortable:
const el = document.getElementById('items-list');
const sortable = new Sortable(el, {
animation: 150,
ghostClass: 'sortable-ghost'
});
Ключевые параметры:
animation — плавность анимации перемещения.ghostClass — CSS-класс для отображения перетаскиваемого
элемента.handle — селектор для области, за которую можно тянуть
элемент.draggable — селектор элементов, которые можно
перетаскивать.SortableJS предоставляет множество событий, позволяющих управлять логикой перетаскивания:
onStart — срабатывает при начале перетаскивания.onEnd — срабатывает по завершении перетаскивания.onAdd — срабатывает при добавлении элемента из другого
списка.onUpdate — срабатывает при изменении позиции элемента
внутри списка.onRemove — срабатывает при удалении элемента из
списка.Пример обработки события onEnd:
sortable.option('onEnd', function(evt) {
console.log(`Элемент ${evt.item.textContent} перемещён с позиции ${evt.oldIndex} на ${evt.newIndex}`);
});
SortableJS поддерживает взаимодействие нескольких списков через
параметр group.
const groupOptions = {
group: 'shared',
animation: 150
};
Sortable.create(document.getElementById('list1'), groupOptions);
Sortable.create(document.getElementById('list2'), groupOptions);
Особенности:
group.name — имя группы, элементы которой можно
перемещать между списками.group.pull — определяет, можно ли вынимать элементы из
списка.group.put — разрешает или запрещает добавление
элементов в список.Причины:
draggable, и по умолчанию библиотека
не видит перетаскиваемые элементы.pointer-events: none или
user-select: none на элементах может блокировать
перетаскивание.Решение:
const sortable = new Sortable(el, {
draggable: '.sortable-item',
handle: '.handle',
animation: 150
});
На сенсорных экранах перетаскивание может не работать корректно.
Решения:
touch через библиотеку
SortableJS без дополнительных действий, но убедиться, что
родительский контейнер не блокирует события
touchstart.-webkit-user-drag: element; для
элементов, чтобы улучшить отзывчивость на мобильных устройствах.Причины:
group.name различен).pull установлен как false.Решение:
const options = {
group: {
name: 'shared',
pull: true,
put: true
},
animation: 150
};
Если элементы перетаскиваются, но состояние списка не синхронизируется с данными, возникают ошибки.
Решение:
onEnd для обновления массива
данных:sortable.option('onEnd', function(evt) {
const item = data.splice(evt.oldIndex, 1)[0];
data.splice(evt.newIndex, 0, item);
});
Проблемы:
Решение:
Использовать обертки и специальные адаптеры:
react-sortablejsvuedraggableОбновлять состояние через обработчики событий библиотеки, а не напрямую манипулировать DOM.
forceFallback: true для
улучшения отзывчивости.onMove или onEnd.SortableJS позволяет кастомизировать визуальные эффекты:
ghostClass — стиль перемещаемого элемента.chosenClass — стиль выделенного элемента.dragClass — стиль для элемента во время
перетаскивания.Пример CSS:
.sortable-ghost {
opacity: 0.4;
background-color: #ddd;
}
.sortable-chosen {
border: 2px dashed #999;
}
swap — позволяет менять местами элементы без
стандартного Drag and Drop.sort — можно отключить сортировку для списка, оставив
только возможность перемещения элементов между списками.filter — исключение определённых элементов из
перетаскивания.Sortable.create(el, {
filter: '.no-drag',
onFilter: function(evt) {
console.log('Элемент заблокирован для перетаскивания');
}
});
Синхронизация визуального списка и массива данных критична для правильной работы приложения. Основная стратегия:
onEnd для корректного обновления
массива.const items = ['Элемент 1', 'Элемент 2', 'Элемент 3'];
const sortable = new Sortable(el, {
animation: 150,
onEnd(evt) {
const movedItem = items.splice(evt.oldIndex, 1)[0];
items.splice(evt.newIndex, 0, movedItem);
}
});
Это обеспечивает полное соответствие визуального порядка и состояния данных.