Профилирование

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

Библиотека не требует jQuery или других сторонних зависимостей и имеет современный API, основанный на событиях и конфигурационных опциях. Она активно используется в интерфейсах с динамическим контентом, таких как доски задач, галереи изображений, списки товаров и админ-панели.


Инициализация SortableJS

Для работы с библиотекой необходимо подключить скрипт SortableJS и создать контейнер, элементы которого будут перемещаться:

import Sortable from 'sortablejs';

const list = document.getElementById('items');
const sortable = Sortable.create(list, {
    animation: 150,
    ghostClass: 'sortable-ghost',
    chosenClass: 'sortable-chosen',
    dragClass: 'sortable-drag'
});

Ключевые параметры при инициализации:

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

События SortableJS

SortableJS использует обширную систему событий, которая позволяет отслеживать все стадии перетаскивания и сортировки:

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

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

sortable.option('onUpdate', function (evt) {
    console.log('Элемент перемещен с позиции', evt.oldIndex, 'на позицию', evt.newIndex);
});

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

SortableJS предоставляет гибкие опции для управления взаимодействием с элементами:

  • group — позволяет объединять несколько списков для перетаскивания между ними. Может быть строкой или объектом с настройками pull и put.
  • filter — задает селекторы элементов, которые не должны быть перетаскиваемыми.
  • handle — указывает на элемент внутри элемента списка, за который можно захватывать объект для перетаскивания.
  • draggable — задает CSS-селектор элементов, которые можно перемещать.

Пример объединения двух списков в одну группу:

const listA = document.getElementById('listA');
const listB = document.getElementById('listB');

Sortable.create(listA, { group: 'shared' });
Sortable.create(listB, { group: 'shared' });

Теперь элементы можно перемещать между listA и listB.


Визуальные эффекты и стилизация

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

  • sortable-ghost — элемент, который отображается вместо оригинального во время перемещения.
  • sortable-chosen — элемент, который выбран для перетаскивания.
  • sortable-drag — элемент, находящийся в процессе перемещения.

С помощью CSS можно создать плавные переходы, тени и изменения прозрачности:

.sortable-ghost {
    opacity: 0.4;
}

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

.sortable-drag {
    transform: scale(1.05);
}

Производительность и профилирование

SortableJS оптимизирован для работы с большими списками, но при массивных DOM-структурах важно учитывать профилирование производительности:

  1. Минимизация пересчетов стилей — перемещение элементов вызывает перерасчет layout в браузере. Использование requestAnimationFrame и CSS-анимаций снижает нагрузку.
  2. Использование clone вместо прямого перемещения — при работе с тяжелыми элементами можно клонировать объект для анимации, а оригинал оставить на месте до завершения перемещения.
  3. Делегирование событий — вместо навешивания событий на каждый элемент лучше использовать события контейнера и получать данные через evt.target.
  4. Batch-обновление данных — при изменении порядка списка не стоит обновлять сервер после каждого события. Оптимально собирать изменения и отправлять их пачкой.

Пример профилирования при изменении порядка:

let timer;

sortable.option('onUpdate', function(evt) {
    clearTimeout(timer);
    timer = setTimeout(() => {
        const order = Array.from(list.children).map(item => item.dataset.id);
        console.log('Обновленный порядок:', order);
    }, 100);
});

Интеграция с современными фреймворками

SortableJS легко интегрируется с React, Vue и Angular:

  • React: используется через useRef для получения DOM-элемента и useEffect для инициализации Sortable.
  • Vue: применяется через v-for для элементов списка и директиву ref для контейнера.
  • Angular: инициализация происходит в ngAfterViewInit с использованием @ViewChild для получения ссылки на DOM-элемент.

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


Расширенные возможности

SortableJS поддерживает:

  • Сенсорное управление — плавная работа на мобильных устройствах.
  • Множественные контейнеры и вложенные списки — удобная организация сложных интерфейсов.
  • События dragover и dragenter для интеграции с кастомными обработчиками.
  • API методов: toArray(), sort(), save(), destroy(), что позволяет программно управлять элементами списка.