cloned - клонирование элемента

Библиотека Dragula обеспечивает удобное и гибкое управление перетаскиванием элементов в веб-интерфейсах. Одной из возможностей является клонирование элементов при перетаскивании. Это особенно полезно в интерфейсах с повторяющимися элементами, шаблонами или когда требуется сохранить исходный элемент без перемещения. В Dragula за это отвечает событие cloned и связанный параметр copy.


Включение клонирования

Клонирование активируется через опцию copy при инициализации контейнеров Dragula:

const drake = dragula([container1, container2], {
  copy: true, // включение клонирования
  copySortSource: false // запрет на сортировку источника
});

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

  • copy: true — при перетаскивании создается копия элемента, а оригинал остается на месте.

  • copySortSource — управляет возможностью изменения порядка исходного контейнера.

    • false — элементы в исходном контейнере нельзя переставлять.
    • true — исходный контейнер можно сортировать независимо от клона.

Опция copy может быть функцией для гибкой логики клонирования:

copy: function (el, source) {
  return source.id === 'template-container';
}

В этом случае элементы будут клонироваться только из контейнера с идентификатором template-container.


Событие cloned

Dragula предоставляет событие cloned, которое вызывается после создания копии элемента. Это позволяет выполнить дополнительные действия с клоном, например, изменить его идентификатор, добавить атрибуты или стили:

drake.on('cloned', function (clone, original, type) {
  console.log(clone, original, type);
  clone.id = 'clone-' + original.id;
});

Параметры события:

  • clone — новый элемент, который был создан.

  • original — исходный элемент, который был перетащен.

  • type — тип клонирования:

    • "copy" — если элемент был клонирован.
    • "mirror" — если элемент используется как визуальное представление при перетаскивании (Dragula создаёт “зеркало” элемента).

Управление стилями клона

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

drake.on('cloned', function (clone, original, type) {
  clone.classList.add('cloned-item');
  clone.style.border = '2px dashed #ccc';
});

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


Практическая логика клонирования

  1. Использование шаблонов: элементы-шаблоны остаются на месте, а их копии перемещаются по другим контейнерам.
  2. Множественные целевые контейнеры: одна копия может быть перемещена в несколько контейнеров без потери исходного элемента.
  3. Создание динамических списков: каждый клон может иметь уникальный идентификатор или порядковый номер.

Пример с динамическим присвоением идентификатора:

let cloneCounter = 1;

drake.on('cloned', function(clone, original, type) {
  clone.id = 'item-' + cloneCounter++;
});

Ограничение клонирования по контейнерам

Функция copy позволяет ограничивать клонирование по источнику:

copy: function (el, source) {
  return source.classList.contains('draggable-template');
}

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


Особенности взаимодействия с другими событиями

  • drop: после того как клон помещен в новый контейнер, событие drop срабатывает для клона, а оригинальный элемент остается в исходном контейнере.
  • remove: удаление клона не влияет на исходный элемент.
  • shadow: визуальное представление перемещаемого элемента не заменяет клон; это помогает избежать путаницы между зеркалом элемента и фактической копией.

Советы по использованию

  • Использовать cloned для модификации клонов после их создания.
  • Разграничивать классы для оригиналов и клонов.
  • Применять уникальные идентификаторы для элементов-клонов при динамическом создании списков.
  • Контролировать поведение через функцию copy, чтобы клонировались только нужные элементы.

Клонирование в Dragula — это мощный инструмент для создания динамических и интерактивных интерфейсов. Оно позволяет сохранять исходные элементы, расширять возможности перетаскивания и создавать гибкие пользовательские сценарии.