Композиция функциональности

Dragula — это легковесная JavaScript-библиотека для реализации перетаскивания элементов между контейнерами. Она минимально зависит от внешних библиотек и обеспечивает удобное API для управления событиями drag-and-drop. Основной принцип работы основан на автоматическом определении «перетаскиваемых» элементов и контейнеров, а также обработке всех взаимодействий с мышью или тач-устройствами.

Ключевые моменты работы Dragula:

  • Контейнеры: Dragula работает с набором контейнеров, которые передаются при инициализации. Каждый контейнер может содержать несколько элементов, которые подлежат перетаскиванию.
  • Элементы: Любой элемент внутри контейнера может быть перетаскиваемым, при условии, что не заданы ограничения.
  • События: Dragula предоставляет богатый набор событий для отслеживания процесса перетаскивания: drag, drop, over, out, cancel, cloned и другие.

Инициализация и базовое использование

Создание экземпляра Dragula происходит через вызов функции dragula(containers, options), где containers — массив DOM-элементов, а options — объект конфигурации.

const containers = [document.getElementById('left'), document.getElementById('right')];
const drake = dragula(containers, {
    moves: (el, source, handle, sibling) => true,
    accepts: (el, target, source, sibling) => true,
    copy: false,
    revertOnSpill: true
});

Пояснение ключевых опций:

  • moves(el, source, handle, sibling): функция, определяющая, можно ли перемещать конкретный элемент.
  • accepts(el, target, source, sibling): функция, определяющая, можно ли помещать элемент в целевой контейнер.
  • copy: если true, перетаскиваемый элемент будет копироваться вместо перемещения.
  • revertOnSpill: если элемент «вывалился» за пределы контейнеров, он возвращается на исходное место.

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

Dragula предоставляет детальный контроль за процессом drag-and-drop через события:

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

Пример подписки на события:

drake.on('drag', (el) => {
    el.style.opacity = '0.5';
});

drake.on('drop', (el, target) => {
    el.style.opacity = '1';
    console.log(`Элемент перемещён в контейнер: ${target.id}`);
});

drake.on('over', (el, container) => {
    container.classList.add('highlight');
});

drake.on('out', (el, container) => {
    container.classList.remove('highlight');
});

Продвинутая настройка поведения

Фильтрация элементов Можно исключить определённые элементы из перетаскивания с помощью moves:

moves: (el, source, handle) => !el.classList.contains('no-drag')

Копирование элементов Если необходимо, чтобы элементы дублировались вместо перемещения, используется опция copy. Событие cloned позволяет контролировать скопированный элемент.

Ограничение контейнеров С помощью accepts можно реализовать сложные правила, например, разрешить помещать элементы только в определённые контейнеры или перед определённым элементом:

accepts: (el, target) => target.id === 'right'

Анимации и визуальные эффекты Хотя Dragula не содержит встроенных анимаций, легко интегрируется с CSS-переходами и классами. Часто используют изменение классов is-moving, gu-transit и gu-mirror для стилизации перетаскиваемого и «зеркального» элемента.

Расширение функциональности

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

  • Синхронизация с данными: при срабатывании drop можно обновлять массив данных в JavaScript или состояние Vue/React.
  • Динамическое добавление контейнеров: drake.containers.push(newContainer) позволяет добавить новые контейнеры без пересоздания экземпляра.
  • Удаление и очистка: drake.destroy() полностью отключает Dragula и удаляет все обработчики событий.

Особенности работы с мобильными устройствами

Dragula автоматически поддерживает сенсорные события. Однако для плавной работы на тач-устройствах рекомендуется:

  • Использовать touch-action: none на контейнерах, чтобы предотвратить конфликт со скроллом.
  • Проверять размеры «зеркального» элемента (mirror) и корректно позиционировать его при движении пальцем.

Практические советы по архитектуре

  • Разделение логики данных и визуального отображения обеспечивает более гибкую интеграцию Dragula в крупные проекты.
  • Обработка событий drop и out позволяет реализовать сложные сценарии, например, перемещение элементов между списками с разными правилами.
  • Использование классов CSS для состояний элементов делает интерфейс визуально отзывчивым и легко настраиваемым.

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