SortableJS — это мощная библиотека для реализации перетаскивания
элементов на веб-странице. Основной способ её подключения — через CDN
или пакетный менеджер. После подключения создается новый экземпляр
Sortable, передавая в конструктор контейнер и объект с
опциями:
import Sortable from 'sortablejs';
const list = document.getElementById('items');
const sortable = new Sortable(list, {
animation: 150,
handle: '.handle',
draggable: '.item',
});
Ключевые параметры:
animation — плавность перемещения элементов.handle — указание области, за которую возможно
перетаскивание.draggable — селектор элементов, которые можно
перемещать.SortableJS поддерживает объединение нескольких списков. Для этого
используется опция group. Она позволяет перемещать элементы
между контейнерами, задавать правила копирования и ограничения
перемещений.
const sortable1 = new Sortable(list1, {
group: 'shared',
animation: 200,
});
const sortable2 = new Sortable(list2, {
group: 'shared',
animation: 200,
});
Особенности group:
name — идентификатор группы.pull — разрешает или запрещает вынос элементов из
списка.put — разрешает или запрещает прием элементов из других
списков.Гибкое использование pull и put позволяет
создавать сложные сценарии, например, односторонние списки, где элементы
можно только перетаскивать в один контейнер.
SortableJS предоставляет широкий набор событий, которые позволяют отслеживать все этапы взаимодействия:
onStart — начало перетаскивания.onEnd — завершение перетаскивания.onAdd — элемент добавлен в другой список.onUpdate — элемент перемещен внутри текущего
списка.onRemove — элемент удален из текущего списка.onSort — любое изменение порядка элементов.Пример обработки событий:
const sortable = new Sortable(list, {
animation: 150,
onEnd: function (evt) {
console.log(`Элемент перемещен с позиции ${evt.oldIndex} на ${evt.newIndex}`);
},
});
Использование событий позволяет интегрировать сортировку с сервером, обновлять базу данных или управлять состоянием интерфейса в реальном времени.
SortableJS поддерживает детальную настройку поведения элементов:
sort — включает или отключает сортировку элементов
внутри контейнера.filter — задает элементы, которые нельзя
перемещать.preventOnFilter — предотвращает действие браузера на
фильтрованных элементах.ghostClass — CSS-класс для копии перетаскиваемого
элемента.chosenClass — CSS-класс для выбранного элемента.Пример фильтрации:
const sortable = new Sortable(list, {
filter: '.non-draggable',
preventOnFilter: false,
});
Элементы с классом .non-draggable не будут перемещаться,
при этом другие элементы останутся интерактивными.
Иногда необходимо, чтобы элемент при перетаскивании оставался в
исходном списке и одновременно создавал копию в другом. Для этого
используется функция clone и pull: 'clone' в
группе:
const sortableSource = new Sortable(listSource, {
group: {
name: 'clone-group',
pull: 'clone',
put: false,
},
animation: 150,
});
const sortableTarget = new Sortable(listTarget, {
group: 'clone-group',
animation: 150,
});
Этот подход подходит для реализации функционала «добавить элемент в корзину», когда оригинал остается на месте, а копия добавляется в другой контейнер.
SortableJS корректно работает с динамическим изменением DOM. Если
элементы создаются или удаляются после инициализации, достаточно
обновить список вызовом метода sort() или просто позволить
библиотеке работать с новыми элементами через draggable
селектор.
const newItem = document.createElement('li');
newItem.className = 'item';
newItem.textContent = 'Новый элемент';
list.appendChild(newItem);
После добавления элемент автоматически станет перетаскиваемым, если
селектор совпадает с draggable.
Для реализации вложенных сортируемых списков
(nested lists) можно использовать отдельные экземпляры
Sortable для каждого уровня:
const parentSortable = new Sortable(parentList, {
group: 'nested',
animation: 150,
});
const childSortable = new Sortable(childList, {
group: 'nested',
animation: 150,
});
Каждый уровень управляется отдельно, что позволяет создавать многоуровневые деревья с перетаскиванием элементов между уровнями.
SortableJS хорошо интегрируется с Vue, React и Angular через
официальные обертки или нативные методы. Для React, например,
используется компонент SortableContainer и
SortableElement:
import { SortableContainer, SortableElement } from 'react-sortablejs';
const SortableItem = SortableElement(({ value }) => <li>{value}</li>);
const SortableList = SortableContainer(({ items }) => (
<ul>
{items.map((value, index) => (
<SortableItem key={index} index={index} value={value} />
))}
</ul>
));
Это обеспечивает реактивное обновление состояния при изменении порядка элементов, сохраняя преимущества виртуального DOM.
Для больших списков важно учитывать производительность. Рекомендации:
animation с минимальной задержкой для
плавного перемещения.filter вместо удаления
из DOM.draggable.onMove и
onUpdate, особенно если они запускают тяжелые вычисления
или запросы к серверу.Эти меры обеспечивают стабильную работу интерфейса даже при сотнях элементов и сложных сценариях взаимодействия.