Симуляция drag and drop

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

Подключение библиотеки может быть выполнено через npm:

npm install sortablejs

или через CDN:

<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>

После подключения создаётся экземпляр Sortable, которому передаётся DOM-элемент контейнера с элементами списка.

const list = document.getElementById('items');
const sortable = new Sortable(list, {
    animation: 150,
    ghostClass: 'sortable-ghost',
    handle: '.handle'
});

Ключевые параметры:

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

События и их обработка

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

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

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

const sortable = new Sortable(list, {
    animation: 150,
    onEnd: function (evt) {
        console.log(`Элемент ${evt.item.textContent} перемещён с позиции ${evt.oldIndex} на ${evt.newIndex}`);
    }
});

Полезные свойства объекта события (evt):

  • evt.item — DOM-элемент, который был перемещён.
  • evt.oldIndex — индекс элемента до перемещения.
  • evt.newIndex — индекс элемента после перемещения.
  • evt.from — родительский контейнер элемента до перемещения.
  • evt.to — контейнер, куда перемещён элемент.

Настройка групп и мультисписков

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

Пример:

const groupOptions = {
    group: 'shared', // общая группа
    animation: 200,
    pull: true,      // разрешить перетаскивание в другие списки
    put: true        // разрешить вставку из других списков
};

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

Параметры групп:

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

Ограничение перемещений и пользовательские условия

Для ограничения перемещения элементов можно использовать функцию filter и draggable:

new Sortable(list, {
    draggable: '.draggable', // только элементы с этим классом можно перетаскивать
    filter: '.no-drag',      // элементы с этим классом нельзя перетаскивать
    onFilter: function (evt) {
        console.log(`Элемент ${evt.item.textContent} не может быть перемещён`);
    }
});

Также можно управлять перемещением через onMove:

new Sortable(list, {
    onMove: function (evt, originalEvent) {
        return !evt.related.classList.contains('locked'); // запрещает перемещение на элементы с классом 'locked'
    }
});

Пользовательские анимации и стили

SortableJS позволяет кастомизировать визуальные эффекты перетаскивания через CSS и встроенные параметры:

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

Пример CSS:

.sortable-ghost {
    opacity: 0.4;
    background-color: #ccc;
}

.sortable-chosen {
    border: 2px solid #000;
}

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

SortableJS автоматически работает с элементами, добавленными после инициализации. Если требуется добавление новых элементов в список и автоматическое применение drag-and-drop, достаточно обновить контейнер DOM, и библиотека будет работать корректно:

const list = document.getElementById('items');

const sortable = new Sortable(list, { animation: 150 });

const newItem = document.createElement('li');
newItem.textContent = 'Новый элемент';
list.appendChild(newItem);

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

SortableJS легко интегрируется с популярными фронтенд-фреймворками:

  • React: используется через обёртку react-sortablejs.
  • Vue: через vuedraggable.
  • Angular: через ngx-sortablejs.

Пример интеграции с Vue:

<template>
  <draggable v-model="items" group="shared" animation="200">
    <div v-for="item in items" :key="item.id">{{ item.name }}</div>
  </draggable>
</template>

<script>
import draggable from 'vuedraggable';
export default {
  components: { draggable },
  data() {
    return {
      items: [{id:1, name:'A'}, {id:2, name:'B'}]
    };
  }
}
</script>

SortableJS обеспечивает полный контроль над процессом перетаскивания, гибко настраивается через параметры, события и CSS, что делает её универсальным инструментом для реализации интерактивных списков и сложных drag-and-drop интерфейсов.