Обработка данных

SortableJS — это мощная библиотека для реализации перетаскивания элементов в веб-приложениях на JavaScript. Она позволяет создавать интерактивные списки с возможностью сортировки, изменять порядок элементов динамически и интегрироваться с другими интерфейсными компонентами.

Создание базового списка начинается с инициализации Sortable на выбранном контейнере:

import Sortable from 'sortablejs';

const list = document.getElementById('sortable-list');

const sortable = new Sortable(list, {
    animation: 150,
    ghostClass: 'sortable-ghost',
    chosenClass: 'sortable-chosen',
    dragClass: 'sortable-drag'
});

Ключевые опции:

  • animation — задаёт плавность анимации при перемещении элементов.
  • ghostClass — класс, применяемый к элементу-заглушке во время перетаскивания.
  • chosenClass — класс выбранного элемента.
  • dragClass — класс, применяемый к элементу в момент активного перетаскивания.

Работа с событиями

SortableJS предоставляет широкий набор событий, позволяющих контролировать процесс сортировки и реагировать на действия пользователя.

Основные события:

  • onStart — вызывается при начале перетаскивания элемента.
  • onEnd — срабатывает после завершения перемещения элемента.
  • onAdd — используется, когда элемент добавлен из другого списка.
  • onUpdate — вызывается, если порядок элементов внутри списка изменён.
  • onRemove — срабатывает при удалении элемента из списка.

Пример использования событий:

sortable.on('onEnd', function (evt) {
    console.log(`Элемент ${evt.item.textContent} перемещён с позиции ${evt.oldIndex} на ${evt.newIndex}`);
});

Настройка взаимодействия нескольких списков

SortableJS поддерживает работу с несколькими списками, позволяя перемещать элементы между ними с помощью опции group. Это особенно полезно при создании досок задач, таблиц или kanban-интерфейсов.

const groupOptions = {
    group: 'shared',
    animation: 150,
    pull: true,
    put: true
};

Sortable.create(document.getElementById('list1'), groupOptions);
Sortable.create(document.getElementById('list2'), groupOptions);

Пояснения по опциям группы:

  • group — имя группы списков, элементы которой можно перемещать между контейнерами.
  • pull — разрешает выносить элементы из списка.
  • put — разрешает вставку элементов из других списков.

Динамическое управление элементами

SortableJS позволяет программно добавлять и удалять элементы из списка, а также изменять их порядок.

Добавление элемента:

const newItem = document.createElement('li');
newItem.textContent = 'Новый элемент';
list.appendChild(newItem);
sortable.sort([...list.children].map(el => el));

Удаление элемента:

list.removeChild(list.children[2]);

Изменение порядка элементов через метод sort:

sortable.sort([2, 0, 1]); // меняет порядок элементов на заданный массив индексов

Работа с ограничениями и фильтрами

Можно запрещать перетаскивание определённых элементов с помощью опций filter и preventOnFilter:

Sortable.create(list, {
    filter: '.no-drag',
    preventOnFilter: false,
    animation: 150
});
  • filter — селектор элементов, для которых перетаскивание запрещено.
  • preventOnFilter — управляет предотвращением стандартного поведения браузера при фильтрации.

Настройка визуального отображения

Для удобства пользователя важно настроить визуальные эффекты:

  • Класс заглушки (ghostClass) показывает, как элемент будет перемещён.
  • Класс выбранного элемента (chosenClass) выделяет активный элемент.
  • Плавность анимации (animation) делает перемещение элементов естественным.
.sortable-ghost {
    opacity: 0.4;
    border: 1px dashed #ccc;
}

.sortable-chosen {
    background-color: #f0f0f0;
}

.sortable-drag {
    cursor: grabbing;
}

Интеграция с обработкой данных

SortableJS легко интегрируется с сохранением состояния на сервере. После изменения порядка элементов можно отправить обновлённый порядок в базу данных:

sortable.on('onEnd', function (evt) {
    const order = [...list.children].map(el => el.dataset.id);
    fetch('/update-order', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({order})
    });
});

Это обеспечивает синхронизацию интерфейса с серверной логикой и позволяет реализовать динамические списки с постоянным порядком элементов.


Работа с вложенными списками

SortableJS поддерживает вложенные списки (nested lists), что позволяет создавать сложные структуры:

Sortable.create(document.getElementById('parent-list'), {
    group: 'nested',
    animation: 150,
    fallbackOnBody: true,
    swapThreshold: 0.65
});
  • fallbackOnBody — временно переносит элемент на тело документа при перетаскивании, чтобы избежать проблем с overflow.
  • swapThreshold — чувствительность к обмену элементов при пересечении.

Сохранение и восстановление состояния

Для динамических интерфейсов важно сохранять порядок элементов при обновлении страницы. Это реализуется через хранение массива идентификаторов элементов и повторную сортировку при загрузке:

const savedOrder = JSON.parse(localStorage.getItem('listOrder')) || [];
if (savedOrder.length) {
    sortable.sort(savedOrder);
}

sortable.on('onEnd', function () {
    const order = [...list.children].map(el => el.dataset.id);
    localStorage.setItem('listOrder', JSON.stringify(order));
});

Такой подход обеспечивает постоянство пользовательских изменений и удобство работы с динамическими данными.


Производительность и оптимизация

  • Использование animation с небольшим значением (например, 150–200 мс) улучшает отзывчивость интерфейса.
  • Фильтрация элементов через filter уменьшает количество ненужных обработчиков.
  • Вложенные списки требуют fallbackOnBody только при необходимости, чтобы избежать лишнего рендеринга.

SortableJS сочетает гибкость и простоту, предоставляя полный контроль над интерактивными списками. С его помощью можно строить сложные интерфейсы с динамическими данными, поддержкой нескольких списков, анимацией и сохранением состояния, обеспечивая при этом высокую производительность и удобство пользователя.