Хуки для SortableJS

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

Каждый хук принимает объект события, содержащий ключевую информацию о текущей операции. Основные свойства этого объекта включают:

  • item — DOM-элемент, который перемещается.
  • from — родительский контейнер исходного элемента.
  • to — контейнер, куда элемент перемещается.
  • oldIndex — индекс элемента до перемещения.
  • newIndex — индекс элемента после перемещения.
  • clone — клон элемента (если используется опция ghost).
  • pullMode — режим перемещения при взаимодействии между списками.

Все хуки можно условно разделить на события начала, в процессе и после завершения сортировки.


События начала сортировки

  1. onChoose Срабатывает, когда элемент выбран для перетаскивания, но фактическое перемещение ещё не началось. Применение: можно выделить элемент визуально или сохранить его исходные данные. Пример:

    new Sortable(list, {
      onChoose: function (evt) {
        evt.item.style.backgroundColor = 'lightblue';
      }
    });
  2. onStart Вызывается, когда перетаскивание фактически начинается. Отличие от onChoose в том, что элемент уже перемещается. Позволяет создавать визуальные эффекты для «перетаскиваемого» объекта и запускать анимации.


События в процессе перемещения

  1. onMove Срабатывает каждый раз, когда элемент перемещается над допустимым контейнером или другим элементом. Можно использовать для динамического контроля: блокировка перемещения, изменение индекса. Пример использования:

    new Sortable(list, {
      onMove: function (evt) {
        return evt.related.className.indexOf('disabled') === -1;
      }
    });

    В данном случае элемент не будет перемещаться над элементами с классом disabled.

  2. onChange Вызывается, когда порядок элементов изменяется в пределах одного контейнера. Полезно для обновления интерфейса или синхронизации состояния с сервером.


События завершения сортировки

  1. onEnd Срабатывает после завершения перетаскивания, независимо от того, было ли оно успешным или отменено. Обычно используется для очистки временных стилей и завершения визуальных эффектов.

  2. onUpdate Срабатывает, когда элемент был перемещён в пределах одного контейнера. Отличие от onEnd в том, что onUpdate вызывается только при реальном изменении порядка элементов.

  3. onAdd Срабатывает, когда элемент добавлен из другого контейнера. Объект события позволяет определить исходный список и новый контейнер. Полезно при синхронизации данных между списками.

  4. onRemove Срабатывает, когда элемент удаляется из текущего контейнера и перемещается в другой. Применяется для логики обновления исходного списка и хранения состояния.

  5. onSort Вызывается при любом изменении порядка элементов, как внутри контейнера, так и при перемещении между списками.

  6. onFilter Срабатывает, если пользователь пытается переместить элемент, соответствующий фильтру. Опция filter позволяет задать селектор элементов, которые нельзя перемещать.


Особенности хуков

  • Все хуки получают один объект события evt. Он содержит не только DOM-элементы, но и данные состояния сортировки, такие как индексы и контейнеры.
  • Хуки можно комбинировать. Например, onStart для анимации, onMove для блокировки, onEnd для очистки.
  • Хуки работают синхронно. Если требуется асинхронная логика, её необходимо оборачивать в промисы или таймауты.

Пример комплексного использования хуков

new Sortable(list, {
  animation: 150,
  ghostClass: 'ghost',
  filter: '.disabled',
  onChoose: evt => evt.item.style.opacity = '0.5',
  onStart: evt => console.log('Начало:', evt.item),
  onMove: evt => evt.related.className.indexOf('disabled') === -1,
  onUpdate: evt => console.log('Порядок обновлён', evt.oldIndex, '→', evt.newIndex),
  onAdd: evt => console.log('Элемент добавлен из другого списка', evt.from),
  onRemove: evt => console.log('Элемент удалён из этого списка', evt.from),
  onEnd: evt => evt.item.style.opacity = '1'
});

В этом примере реализован полный цикл: выбор элемента, перетаскивание, динамическая фильтрация, обновление порядка и визуальная очистка.


Рекомендации по использованию хуков

  • Для крупных списков и интенсивных операций рекомендуется минимизировать DOM-манипуляции внутри хуков, чтобы не снижать производительность.
  • Использование onMove для динамической блокировки перемещения позволяет создавать гибкие правила сортировки, включая условия между различными списками.
  • Хуки onAdd и onRemove упрощают интеграцию с состоянием приложения, например, при работе с Vue, React или Redux.
  • Любые визуальные изменения, сделанные в onChoose или onStart, должны быть откатаны в onEnd для корректного отображения элементов.

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