Dragula — это лёгкая библиотека для реализации drag-and-drop
функционала в веб-приложениях. Она предназначена для управления
перетаскиванием элементов между контейнерами, обеспечивая минимальную
конфигурацию и высокую гибкость. Основой работы библиотеки является
создание экземпляра dragula с массивом контейнеров,
элементы которых можно перетаскивать.
const containers = [document.getElementById('left'), document.getElementById('right')];
const drake = dragula(containers);
Здесь containers — массив элементов DOM, между которыми
будет возможна перетаскиваемая сортировка. После инициализации
экземпляра, drake автоматически добавляет слушатели событий
мыши для всех элементов контейнеров.
Dragula позволяет детально настраивать поведение перетаскивания через опции, передаваемые при создании экземпляра:
const drake = dragula(containers, {
moves: (el, source, handle, sibling) => handle.classList.contains('handle'),
accepts: (el, target, source, sibling) => !target.classList.contains('disabled'),
copy: false,
revertOnSpill: true
});
true или
false.true, элементы при
перетаскивании копируются вместо перемещения.Эти параметры позволяют создавать сложные интерфейсы с ограничениями на перетаскивание и разными типами элементов.
Dragula предоставляет набор событий, которые дают полный контроль над процессом перетаскивания:
drag — срабатывает при начале
перетаскивания элемента.dragend — срабатывает после завершения
перетаскивания, когда элемент отпущен.drop — срабатывает при успешном
отпускании элемента в контейнере.over / out — фиксируют
наведение или выход элемента над контейнером.cloned — срабатывает при клонировании
элемента (если включён режим копирования).Пример использования события:
drake.on('drop', (el, target, source, sibling) => {
console.log(`Элемент ${el.textContent} перемещён в контейнер ${target.id}`);
});
События позволяют интегрировать Dragula с backend-логикой, обновлять данные в базе и анимацию интерфейса.
Стандартная реализация Dragula ориентирована на мышь и сенсорные устройства, однако в современных веб-приложениях важна поддержка клавиатурной навигации. Для этого необходимо:
tabindex="0".keydown.Пример расширения Dragula для клавиатурного управления:
document.querySelectorAll('.draggable').forEach(item => {
item.setAttribute('tabindex', '0');
item.addEventListener('keydown', (e) => {
const parent = item.parentElement;
if (e.key === 'ArrowUp' && item.previousElementSibling) {
parent.insertBefore(item, item.previousElementSibling);
}
if (e.key === 'ArrowDown' && item.nextElementSibling) {
parent.insertBefore(item.nextElementSibling, item);
}
if (e.key === 'Enter') {
console.log(`Выбран элемент: ${item.textContent}`);
}
});
});
Особенности реализации:
Таким образом, Dragula можно интегрировать с клавиатурной навигацией, сохраняя доступность интерфейса для пользователей с ограниченными возможностями.
Dragula автоматически не отслеживает новые элементы, добавленные в DOM после инициализации. Для динамических списков необходимо:
drake.containers.push(newContainer) при создании нового
контейнера.Пример динамического добавления:
const newItem = document.createElement('div');
newItem.className = 'draggable';
newItem.textContent = 'Новый элемент';
document.getElementById('left').appendChild(newItem);
// Сделать элемент фокусируемым и добавить обработчик клавиатуры
newItem.setAttribute('tabindex', '0');
newItem.addEventListener('keydown', handleKeyboardNavigation);
Это обеспечивает согласованное поведение интерфейса и предотвращает потерю доступности при добавлении новых элементов.
Dragula легко интегрируется с React, Vue и Angular:
ref, события Dragula синхронизировать с состоянием
компонентов.v-for для рендеринга
элементов, привязывать контейнеры через ref и управлять
событиями через методы компонента.ng2-dragula, используя директивы для
контейнеров и элементов.Клавиатурная навигация при этом реализуется аналогично — фокусируемые элементы и обработчики клавиатуры работают вне зависимости от фреймворка.
role="list", role="listitem").Подход, основанный на клавиатурной навигации, позволяет Dragula быть не только мощной библиотекой для drag-and-drop, но и полностью соответствовать современным стандартам доступности.