Структура DOM-элементов

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


Родительский контейнер

Основной элемент, с которым работает SortableJS, — это контейнер (container). Контейнер — это любой элемент DOM, который содержит дочерние элементы, подлежащие сортировке. Чаще всего это <ul>, <ol>, <div> или <table>.

<ul id="sortable-list">
    <li>Элемент 1</li>
    <li>Элемент 2</li>
    <li>Элемент 3</li>
</ul>

Контейнер определяется при инициализации:

new Sortable(document.getElementById('sortable-list'), {
    animation: 150
});

Ключевые моменты:

  • Контейнер должен существовать в DOM на момент инициализации.
  • Библиотека работает только с прямыми потомками контейнера.
  • Можно управлять классами контейнера для стилизации элементов при перетаскивании.

Дочерние элементы

Элементы, которые подлежат сортировке, называются items. По умолчанию SortableJS считает всеми прямыми потомками контейнера. Каждый item становится «перетаскиваемым» и может быть перемещён в пределах контейнера или между контейнерами.

new Sortable(list, {
    draggable: 'li'
});

Особенности работы с дочерними элементами:

  • draggable позволяет указать селектор для элементов, которые будут перемещаемыми.
  • Можно исключить элементы с помощью опции filter.
  • Любой элемент, не являющийся прямым потомком контейнера, игнорируется.

Вложенные списки

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

<ul id="parent-list">
    <li>
        Элемент A
        <ul class="child-list">
            <li>Подэлемент A1</li>
            <li>Подэлемент A2</li>
        </ul>
    </li>
    <li>Элемент B</li>
</ul>
new Sortable(document.querySelector('.child-list'), {
    group: 'nested',
    animation: 100
});

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

  • Опция group позволяет соединять контейнеры для перемещения элементов между ними.
  • Каждый вложенный контейнер должен быть отдельной инициализацией Sortable.
  • Динамическое добавление элементов в DOM требует повторной привязки Sortable или использования observer.

Обновление DOM при сортировке

SortableJS напрямую изменяет порядок DOM-узлов. Это означает, что после перетаскивания визуальный порядок элементов совпадает с их фактическим порядком в DOM:

list.addEventListener('sortupdate', function (event) {
    console.log('Новый порядок элементов:', list.children);
});

Ключевые моменты:

  • Перетаскивание не клонирует элементы, а перемещает их.
  • Любые события, привязанные к элементам, остаются активными.
  • Можно использовать события onEnd, onAdd, onUpdate для синхронизации с данными на сервере.

Использование атрибутов и классов

Для более точного контроля над элементами можно использовать атрибуты data-* или CSS-классы. Это позволяет фильтровать элементы, определять их уникальность и взаимодействовать с ними при перетаскивании.

<li data-id="1" class="draggable-item">Элемент 1</li>
<li data-id="2" class="draggable-item">Элемент 2</li>
new Sortable(list, {
    draggable: '.draggable-item'
});

Особенности:

  • Классы и атрибуты помогают реализовать условное перетаскивание.
  • Можно комбинировать draggable и filter для сложных сценариев.
  • Использование уникальных идентификаторов упрощает синхронизацию с базой данных.

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

SortableJS добавляет временные CSS-классы к элементам во время перетаскивания:

  • .sortable-chosen — элемент, который выбран для перемещения.
  • .sortable-ghost — прозрачный «призрак» элемента во время перетаскивания.
  • .sortable-drag — элемент в процессе перетаскивания (иногда совпадает с ghost).

Применение стилей через классы:

.sortable-ghost {
    opacity: 0.4;
    border: 2px dashed #aaa;
}

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


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

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

  • Использовать MutationObserver или обновлять Sortable через sort() или destroy() и повторную инициализацию.
  • Следить за сохранением атрибутов и классов, иначе новые элементы могут не быть перетаскиваемыми.
const newItem = document.createElement('li');
newItem.textContent = 'Новый элемент';
list.appendChild(newItem);

После добавления можно вызвать sortableInstance.sort() или повторно инициализировать контейнер.


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