Dragula — это лёгкая библиотека для реализации drag-and-drop функционала в веб-приложениях на JavaScript. Она позволяет перетаскивать элементы между контейнерами и внутри одного контейнера, сохраняя при этом простоту подключения и минимальную настройку. Основная цель Dragula — предоставить разработчику интуитивно понятный API без необходимости писать сложные обработчики событий вручную.
Для использования Dragula достаточно подключить библиотеку через CDN или npm-пакет:
<script src="https://unpkg.com/dragula/dist/dragula.min.js"></script>
<link rel="stylesheet" href="https://unpkg.com/dragula/dist/dragula.min.css">
Инициализация выполняется очень просто:
const containers = [document.getElementById('left'), document.getElementById('right')];
const drake = dragula(containers);
В этом примере drake создаёт возможность перетаскивания
элементов между двумя контейнерами left и
right.
Dragula предоставляет несколько ключевых методов и событий:
Методы:
drake.cancel() — отменяет текущее перетаскивание.drake.remove() — удаляет элемент из DOM после
перетаскивания.drake.start() и drake.end() — программно
запускают или завершают drag-сессию.События:
drag — срабатывает при начале перетаскивания.drop — при успешном размещении элемента.over и out — при наведении элемента на
контейнер или выходе из него.cloned — при клонировании элемента, если включена
соответствующая опция.События подписываются через метод on:
drake.on('drop', (el, target, source, sibling) => {
console.log('Элемент перемещён:', el);
});
Для адаптации поведения Dragula предусмотрены опции при инициализации:
moves — функция, определяющая, можно
ли перемещать элемент. Возвращает true или
false.accepts — функция, определяющая, можно
ли помещать элемент в конкретный контейнер.copy — если true, элемент
будет клонироваться при перетаскивании.revertOnSpill — возвращает элемент на
место, если он не был успешно помещён в контейнер.Пример кастомной конфигурации:
const drake = dragula(containers, {
moves: (el, source, handle, sibling) => handle.classList.contains('handle'),
accepts: (el, target) => !target.classList.contains('no-drop'),
copy: false,
revertOnSpill: true
});
Здесь перемещать элементы можно только за «ручку»
(handle), а помещать — только в контейнеры без класса
no-drop.
Dragula по умолчанию добавляет классы, которые можно использовать для CSS-стилизации:
gu-mirror — элемент, который отображается во время
перетаскивания.gu-transit — элемент, который перемещается из исходного
контейнера.gu-hide — временно скрывает оригинальный элемент.С помощью этих классов можно создавать динамическую визуальную обратную связь, например, изменять цвет элемента при перетаскивании или добавлять тень:
.gu-mirror {
background-color: rgba(0, 123, 255, 0.3);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
border-radius: 4px;
}
.gu-transit {
opacity: 0.6;
}
Для адаптивного дизайна важно учитывать размер и позицию элементов на разных экранах. Можно динамически изменять стили через Jav * aScript:
drake.on('drag', (el) => {
el.style.width = el.offsetWidth + 'px';
});
Это предотвращает «скачки» ширины при перетаскивании в контейнер меньшего размера.
Dragula легко совмещается с современными CSS-фреймворками, такими как Bootstrap или Tailwind. При этом можно использовать классы фреймворка для:
Пример с Tailwind:
.gu-mirror {
@apply bg-blue-200 shadow-lg rounded-md;
}
.gu-transit {
@apply opacity-60;
}
Для плавного перемещения можно комбинировать Dragula с CSS-переходами:
.gu-transit, .gu-mirror {
transition: transform 0.2s ease, opacity 0.2s ease;
}
Это создаёт чёткую визуальную связь между исходным и новым положением элемента, особенно на мобильных устройствах.
Если элементы добавляются в контейнеры динамически, Dragula может быть настроен на автообновление контейнеров:
const dynamicContainer = document.getElementById('dynamic');
drake.containers.push(dynamicContainer);
После добавления новых контейнеров, Dragula автоматически начнёт отслеживать перетаскивание элементов в них.
Чтобы элементы оставались на своих местах после перезагрузки страницы, можно использовать локальное хранилище:
drake.on('drop', (el, target) => {
const state = Array.from(target.children).map(e => e.id);
localStorage.setItem(target.id, JSON.stringify(state));
});
При загрузке страницы:
const savedState = JSON.parse(localStorage.getItem('right'));
if (savedState) {
savedState.forEach(id => document.getElementById(id) && right.appendChild(document.getElementById(id)));
}
gu-mirror и gu-transit
для анимации, вместо постоянного изменения inline-стилей.Эта методика позволяет создавать адаптивные, интерактивные интерфейсы, которые корректно работают на различных устройствах, с плавной анимацией и минимальной нагрузкой на DOM. Dragula сочетает простоту использования с гибкостью настройки, что делает её мощным инструментом для реализации drag-and-drop функционала в современном JavaScript-приложении.