Профилирование приложения

Dragula — это легковесная библиотека для реализации перетаскивания элементов (drag-and-drop) в веб-приложениях. Для её использования достаточно подключить пакет через npm или CDN.

Через npm:

npm install dragula

Подключение в коде:

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

При подключении через CDN используется следующий код:

<link rel="stylesheet" href="https://unpkg.com/dragula/dist/dragula.min.css">
<script src="https://unpkg.com/dragula/dist/dragula.min.js"></script>

Инициализация контейнеров

Основной объект Dragula создаётся вызовом функции dragula() с массивом контейнеров, элементы которых будут перетаскиваться.

const containers = [
    document.getElementById('left-panel'),
    document.getElementById('right-panel')
];

const drake = dragula(containers);

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

  • Контейнеры — это элементы DOM, между которыми можно перемещать дочерние элементы.
  • Если не передать массив контейнеров, Dragula создаёт пустой объект для динамического добавления контейнеров позднее.

Основные опции конфигурации

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

  • moves: функция, определяющая, можно ли перетаскивать конкретный элемент.
const drake = dragula(containers, {
    moves: function (el, source, handle, sibling) {
        return handle.classList.contains('draggable-handle');
    }
});
  • accepts: функция, определяющая, можно ли помещать элемент в целевой контейнер.
accepts: function (el, target, source, sibling) {
    return target.id !== 'restricted-container';
}
  • copy: позволяет копировать элемент вместо его перемещения.
copy: true
  • revertOnSpill: возвращает элемент на исходное место, если он был «выброшен» вне контейнеров.
revertOnSpill: true
  • removeOnSpill: удаляет элемент, если он не попал в контейнер.
removeOnSpill: true

События Dragula

Dragula предоставляет ряд событий для обработки различных стадий перетаскивания:

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

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

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

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

drake.on('remove', function(el) {
    console.log('Элемент удалён:', el);
});

Персонализация внешнего вида

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

  • gu-transit — элемент во время перетаскивания.
  • gu-mirror — копия элемента, которая следует за курсором.
  • gu-hide — скрывает оригинальный элемент при копировании.

Можно полностью стилизовать эти классы через CSS для плавной анимации и визуальной обратной связи.

.gu-mirror {
    background-color: rgba(0, 0, 0, 0.1);
    box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
    border-radius: 4px;
}

Динамическое добавление контейнеров и элементов

Dragula поддерживает динамическое обновление списка контейнеров:

const newContainer = document.getElementById('new-panel');
drake.containers.push(newContainer);

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

Копирование и работа с шаблонами

При использовании опции copy: true можно легко реализовать клонирование элементов. Это полезно для интерфейсов, где элементы доступны для многократного перетаскивания в разные контейнеры, например, в конструкторе форм.

const drake = dragula(containers, { copy: true });

drake.on('drop', function(el, target) {
    if (el.dataset.type === 'template') {
        const clone = el.cloneNode(true);
        clone.dataset.type = 'instance';
        target.appendChild(clone);
    }
});

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

Использование функций moves и accepts позволяет создавать сложные логики:

  • Разрешение перемещения только при удерживании определённой части элемента.
  • Запрет перемещения в конкретные контейнеры.
  • Возможность создавать правила, зависящие от состояния приложения.

Интеграция с другими библиотеками

Dragula легко комбинируется с фреймворками Vue, React или Angular, так как работает напрямую с DOM. Для интеграции с виртуальными DOM-структурами важно:

  • Использовать ссылки на реальные DOM-элементы после рендеринга.
  • Обновлять состояние приложения при событии drop для синхронизации с виртуальным DOM.

Производительность и профилирование

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

  • Минимизировать количество событий drag с дорогостоящими вычислениями.
  • Использовать делегирование или throttling при обработке событий.
  • Контролировать количество одновременно перетаскиваемых элементов.

Dragula не хранит внутреннего состояния элементов, что упрощает профилирование и предотвращает утечки памяти.


Этот материал охватывает базовую и продвинутую работу с Dragula: от подключения и инициализации до сложных сценариев интеграции и оптимизации производительности.