Древовидные структуры

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

import dragula from 'dragula';
import 'dragula/dist/dragula.css';

Создание базового контейнера осуществляется через вызов функции dragula с массивом контейнеров:

const containers = [document.getElementById('list1'), document.getElementById('list2')];
const drake = dragula(containers);

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

Настройка ограничений перетаскивания

Dragula предоставляет несколько ключевых опций для контроля поведения элементов:

  • moves — функция, определяющая, какие элементы можно перетаскивать. Возвращает true для разрешённых элементов.
const drake = dragula(containers, {
  moves: (el, source, handle, sibling) => handle.classList.contains('handle')
});
  • accepts — функция для контроля, в какой контейнер можно положить элемент.
accepts: (el, target, source, sibling) => target.id !== 'forbidden'
  • copy — определяет, копируется ли элемент при перетаскивании вместо перемещения.

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

Работа с древовидными структурами

Для реализации древовидных структур Dragula может использоваться совместно с вложенными списками (ul, li или div). Каждый узел дерева становится контейнером для своих дочерних элементов.

Пример структуры:

<ul id="tree">
  <li>
    Узел 1
    <ul>
      <li>Подузел 1.1</li>
      <li>Подузел 1.2</li>
    </ul>
  </li>
  <li>Узел 2</li>
</ul>

Настройка Dragula для такого дерева предполагает сбор всех контейнеров:

const containers = Array.from(document.querySelectorAll('#tree ul'));
const drake = dragula(containers, {
  moves: (el, source, handle, sibling) => el.tagName === 'LI'
});

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

События Dragula

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

  • drag — вызывается при начале перетаскивания.
  • drop — вызывается при успешной установке элемента в новый контейнер.
  • over и out — определяют вход и выход перетаскиваемого элемента над контейнером.
  • cancel — вызывается при отмене перемещения элемента.

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

drake.on('drop', (el, target, source, sibling) => {
  console.log(`Элемент ${el.textContent} перемещен из ${source.id} в ${target.id}`);
});

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

Интеграция с динамическими элементами

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

function addNode(parentId, content) {
  const parent = document.getElementById(parentId);
  const newNode = document.createElement('li');
  newNode.textContent = content;
  let childContainer = parent.querySelector('ul');
  if (!childContainer) {
    childContainer = document.createElement('ul');
    parent.appendChild(childContainer);
    drake.containers.push(childContainer);
  }
  childContainer.appendChild(newNode);
}

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

Визуальные улучшения и ограничения

Dragula не предоставляет встроенного оформления, но его поведение можно улучшать через CSS:

  • Подсветка контейнера при наведении:
.gu-mirror {
  opacity: 0.8;
  background-color: #f0f0f0;
  border: 1px solid #ccc;
}
.gu-transit {
  opacity: 0.5;
}
.gu-over {
  background-color: #e0e0e0;
}
  • Ограничение глубины дерева через проверку в accepts.
  • Управление размером контейнера для поддержки прокрутки при больших списках.

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