Уничтожение экземпляра

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

Метод destroy()

Каждый экземпляр Sortable создается через конструктор или функцию Sortable.create(). Для удаления функционала сортировки используется метод:

const sortable = new Sortable(el, {
    animation: 150,
    ghostClass: 'ghost'
});

// Уничтожение экземпляра
sortable.destroy();

После вызова destroy():

  • Все обработчики событий, привязанные библиотекой к DOM-элементам, удаляются.
  • Классы и атрибуты, добавленные Sortable (sortable-chosen, sortable-ghost и другие), удаляются.
  • Состояние экземпляра становится неактивным, любые попытки дальнейшего использования методов сортировки приведут к ошибкам или не будут работать.

Важно понимать, что метод не удаляет сам DOM-элемент, он только отключает функционал перетаскивания.

Автоматическое удаление при создании нового экземпляра

Если требуется повторное создание Sortable на том же элементе, рекомендуется предварительно уничтожить существующий экземпляр:

if (sortable) {
    sortable.destroy();
}

sortable = new Sortable(el, { animation: 200 });

Это предотвращает накопление нескольких обработчиков событий и возможное дублирование логики.

Обработка событий перед уничтожением

Иногда перед уничтожением требуется выполнить определённые действия, например, сохранить порядок элементов:

sortable.option("onEnd", function(evt) {
    console.log("Элемент перемещен:", evt.item);
});

function removeSortable() {
    // Логика сохранения состояния
    const order = sortable.toArray();
    console.log("Сохраняем порядок:", order);

    sortable.destroy();
}

Метод toArray() позволяет получить текущий порядок элементов перед уничтожением экземпляра.

Уничтожение нескольких экземпляров

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

const sortables = [];

document.querySelectorAll('.sortable-list').forEach(el => {
    const s = new Sortable(el, { animation: 150 });
    sortables.push(s);
});

// Уничтожение всех экземпляров
sortables.forEach(s => s.destroy());
sortables.length = 0;

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

Особенности при работе с фреймворками

В React, Vue или Angular, где DOM-элементы могут удаляться и пересоздаваться, крайне важно вызывать destroy() в момент размонтирования компонента:

Пример для Vue:

mounted() {
    this.sortable = new Sortable(this.$refs.list, { animation: 150 });
},
beforeUnmount() {
    if (this.sortable) {
        this.sortable.destroy();
        this.sortable = null;
    }
}

Пример для React:

useEffect(() => {
    const sortable = new Sortable(ref.current, { animation: 150 });
    return () => {
        sortable.destroy();
    };
}, []);

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

Важные нюансы

  • Вызов destroy() делает экземпляр непригодным для повторного использования. Для повторного включения сортировки необходимо создавать новый экземпляр.
  • Любые дополнительные привязанные вручную события (addEventListener) не удаляются методом destroy(). Их нужно удалять отдельно, если это необходимо.
  • Атрибуты и классы, добавленные библиотекой, будут удалены только для элементов, присутствующих на момент вызова destroy(). Новые элементы, добавленные динамически, не будут автоматически очищены.

Использование в динамических списках

Для динамически изменяемых списков рекомендуется:

  1. Перед изменением DOM уничтожать текущий экземпляр.
  2. После изменения DOM создавать новый экземпляр с актуальными элементами.
  3. При необходимости сохранять порядок элементов через toArray() и восстанавливать его после пересоздания Sortable.

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