Библиотека Shopify Draggable предоставляет мощные инструменты для организации интерактивных drag-and-drop интерфейсов. Работа с множественными drop-зонами является ключевым элементом при создании сложных интерфейсов, где один элемент может быть перемещён в различные контейнеры, и каждый из них должен иметь собственную логику обработки событий.
В Draggable каждая drop-зона представляет собой отдельный
Droppable объект, который может быть
связан с одним или несколькими контейнерами. Для множественных drop-зон
важно понимать, что события drag:start,
drag:over,
drag:enter,
drag:leave и
drag:stop срабатывают отдельно для каждого
контейнера, что позволяет реализовать тонкую настройку поведения
элементов при их перемещении.
import { Draggable, Droppable } from '@shopify/draggable';
const containers = document.querySelectorAll('.container');
const droppables = document.querySelectorAll('.droppable');
const draggable = new Draggable(containers, {
draggable: '.item',
delay: 0,
});
const droppable = new Droppable(droppables, {
draggable: '.item',
});
Для работы с множественными drop-зонами важно различать два основных подхода:
Droppable, который принимает все контейнеры. Такой
подход удобен для простой логики, когда все drop-зоны имеют одинаковое
поведение.const droppable = new Droppable(document.querySelectorAll('.drop-zone'), {
draggable: '.item'
});
Droppable, по одному для
каждого контейнера. Это позволяет задавать уникальные настройки и
события для каждой зоны.document.querySelectorAll('.drop-zone').forEach(zone => {
new Droppable(zone, { draggable: '.item' });
});
Выбор подхода зависит от сложности интерфейса и необходимой гибкости при обработке событий.
Множественные drop-зоны требуют особого внимания к событиям, так как один и тот же элемент может одновременно входить в область нескольких зон. Основные события:
drag:start – срабатывает при начале
перетаскивания любого элемента.drag:over – активируется, когда
элемент наведен над drop-зоной.drag:enter – срабатывает при входе
элемента в drop-зону.drag:leave – фиксирует момент выхода
элемента из зоны.drag:stop – завершает перетаскивание и
позволяет обработать финальное положение элемента.Пример использования событий для множественных зон:
droppable.on('drag:enter', (event) => {
event.dropZone.classList.add('highlight');
});
droppable.on('drag:leave', (event) => {
event.dropZone.classList.remove('highlight');
});
droppable.on('drag:stop', (event) => {
if (event.dropZone) {
event.dropZone.appendChild(event.source);
}
});
Draggable позволяет задавать приоритеты drop-зон и управлять сортировкой элементов. Например, можно ограничить перетаскивание только в определённые контейнеры или запретить перемещение элементов в пустую drop-зону.
droppable.on('drag:stop', (event) => {
const allowedZones = ['.zone-a', '.zone-b'];
if (!allowedZones.includes(event.dropZone.className)) {
event.source.parentNode.appendChild(event.source);
}
});
Также важно учитывать позиционирование внутри зоны. Можно задавать правила вставки элемента перед или после определённых дочерних элементов с помощью методов:
event.dropZone.insertBefore(source, referenceElement)event.dropZone.appendChild(source)Для улучшения UX при работе с множественными drop-зонами часто используют визуальные подсказки:
drag:enter / drag:over)drag:stop)SortableAnimation от Draggable.drop-zone.highlight {
border: 2px dashed #007bff;
background-color: rgba(0, 123, 255, 0.1);
}
droppable.on('drag:enter', (event) => {
event.dropZone.classList.add('highlight');
});
droppable.on('drag:leave', (event) => {
event.dropZone.classList.remove('highlight');
});
Множественные drop-зоны часто используются для перемещения данных
между различными контейнерами. Для этого можно использовать свойства
события event.source (перетаскиваемый элемент) и
event.dropZone (целевой контейнер). Дополнительно можно
хранить данные через dataset элементов:
droppable.on('drag:stop', (event) => {
const itemData = event.source.dataset.id;
const targetZone = event.dropZone.dataset.zone;
console.log(`Элемент ${itemData} перемещен в зону ${targetZone}`);
});
Если контейнеры создаются динамически, необходимо инициализировать
Droppable после добавления элементов в DOM. Для динамических интерфейсов
рекомендуется использовать метод destroy() перед повторной
инициализацией, чтобы избежать дублирования событий.
droppable.destroy();
new Droppable(document.querySelectorAll('.drop-zone'), { draggable: '.item' });
Множественные drop-зоны в Shopify Draggable позволяют создавать высокоинтерактивные интерфейсы с гибкой логикой перетаскивания, точной сортировкой и визуальной обратной связью, обеспечивая профессиональный уровень UX в веб-приложениях.