В библиотеке Shopify Draggable управление состояниями элементов является ключевым аспектом при создании интерактивных интерфейсов. Состояние элемента определяет, как он реагирует на действия пользователя, такие как перетаскивание, захват, отпускание или нахождение над зоной-дропом. Понимание этих состояний позволяет строить более гибкие и отзывчивые UI-компоненты.
Draggable выделяет несколько стандартных состояний элементов:
Idle (покой) Элемент находится в нормальном состоянии, не взаимодействует с пользователем. В этом состоянии отсутствуют активные события перетаскивания. Обычно это исходное состояние всех элементов.
Dragging (перетаскивание) Элемент находится под воздействием действия пользователя: зажат и перемещается. В этом состоянии можно изменить визуальное отображение, добавив тени, изменив прозрачность или масштаб.
draggable.on('drag:start', (event) => {
event.source.classList.add('is-dragging');
});
draggable.on('drag:stop', (event) => {
event.source.classList.remove('is-dragging');
});
Здесь event.source — это DOM-элемент, который
перетаскивается.
Mirror (зеркало) Когда элемент перетаскивается, Draggable создаёт mirror-элемент, который визуально повторяет оригинальный. Mirror позволяет пользователю видеть, что элемент активен, без непосредственного изменения исходного DOM-узла. Mirror создаётся автоматически, но его поведение можно настраивать через события:
draggable.on('mirror:create', (event) => {
event.mirror.classList.add('custom-mirror');
});
draggable.on('mirror:destroy', (event) => {
event.mirror.classList.remove('custom-mirror');
});Over (над дроп-зоной) Когда перетаскиваемый
элемент находится над зоной-дропом, он попадает в состояние
over. Это состояние удобно использовать для визуального
подсвечивания зоны, куда можно переместить элемент.
draggable.on('droppable:over', (event) => {
event.related.classList.add('is-over');
});
draggable.on('droppable:out', (event) => {
event.related.classList.remove('is-over');
});
Здесь event.related — это DOM-элемент
зоны-дропа.
Помимо стандартных, можно создавать свои состояния для более сложной логики. Например, выделение элементов, которые можно перемещать только при определённых условиях:
draggable.on('drag:start', (event) => {
if (!event.source.classList.contains('draggable-enabled')) {
event.cancel(); // предотвращает начало перетаскивания
} else {
event.source.classList.add('is-active');
}
});
Состояния элементов могут переключаться динамически. Например,
mirror-элемент всегда создаётся в момент начала перетаскивания и
уничтожается при отпускании. Если элемент одновременно находится над
зоной-дроп, mirror может наследовать визуальные эффекты
over.
Важно учитывать порядок событий:
Правильная синхронизация этих состояний обеспечивает плавный пользовательский опыт.
Draggable рекомендует использовать CSS-классы для отображения состояний. Основные подходы:
.is-dragging – для активного перетаскивания..is-over – для зоны-дропа при наведении..is-active – для элементов, доступных к
перетаскиванию..custom-mirror – для mirror с пользовательской
стилизацией.Пример CSS:
.is-dragging {
opacity: 0.6;
transform: scale(1.05);
z-index: 1000;
}
.is-over {
border: 2px dashed #3498db;
background-color: rgba(52, 152, 219, 0.1);
}
.custom-mirror {
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
pointer-events: none;
}
В многоуровневых интерфейсах можно комбинировать несколько Draggable-инстансов с разными состояниями. Например, списки внутри вкладок, где элементы одних списков можно перемещать только внутрь своего списка. Для этого применяются условия в событиях:
draggable.on('drag:move', (event) => {
if (!event.over || event.over.dataset.listId !== event.source.dataset.listId) {
event.cancel();
}
});
Такой подход обеспечивает строгий контроль над доступными состояниями и действиями пользователя.
С помощью грамотного управления состояниями элементов в Shopify Draggable можно создавать интерфейсы, где пользовательский опыт будет максимально интуитивным и отзывчивым, а логика взаимодействия — чёткой и предсказуемой.