Swappable — это модуль из библиотеки Shopify Draggable,
предназначенный для управления обменом элементов между контейнерами и
внутри одного контейнера с поддержкой drag-and-drop. В отличие от
Sortable, который перемещает элементы по списку,
Swappable ориентирован на обмен позиций
элементов, что особенно удобно для интерфейсов с сетками,
карточками или досками.
Ключевой принцип работы Swappable заключается в том, что каждое перетаскиваемое событие инициирует «swap» между исходным элементом и целевым. Процесс делится на несколько этапов: инициализация, отслеживание движения, определение цели обмена и фактическая замена DOM-элементов.
Для использования Swappable необходимо создать экземпляр
класса с конфигурацией:
import { Swappable } from '@shopify/draggable';
const swappable = new Swappable(document.querySelectorAll('.container'), {
draggable: '.draggable-item',
mirror: {
constrainDimensions: true
}
});
Пояснения параметров:
.container — CSS-селектор
контейнера(ов), внутри которого происходит обмен.draggable — селектор элементов,
которые можно перемещать.mirror.constrainDimensions — опция,
которая фиксирует размеры «зеркального» элемента (элемент, который
визуально перемещается при drag).При инициализации создается слушатель событий для
drag:start, drag:move и
drag:stop. Эти события позволяют отслеживать весь
жизненный цикл перетаскивания и управлять визуальными
эффектами.
При перетаскивании Swappable создает зеркальный
элемент, который визуально повторяет исходный. Зеркало
отделяется от DOM исходного элемента и следует за
курсором, сохраняя размеры и стиль исходника, если включена
опция constrainDimensions.
swappable.on('drag:start', (event) => {
console.log('Начало перетаскивания:', event.source);
});
Ключевой момент: зеркальный элемент не изменяет DOM до завершения drag. Это позволяет выполнять плавные анимации и предотвращает сдвиг других элементов до фактического обмена.
Когда пользователь перемещает элемент, Swappable
постоянно отслеживает позицию курсора относительно других
draggable-элементов. Цель обмена определяется на основе
ближайшего пересечения с другим элементом:
event.over — элемент, над которым находится
курсор.event.source — перетаскиваемый элемент.swappable.on('swappable:swapped', (event) => {
console.log('Элементы обменяны:', event.source, '↔', event.over);
});
Swappable предоставляет набор событий, с помощью которых можно контролировать поведение обмена:
swappable:start — инициируется при
начале drag.swappable:swapped — вызывается после
завершения обмена элементов.swappable:stop — когда drag
прекращается.swappable:over /
swappable:out — при наведении и уходе курсора над
другим элементом.Эти события позволяют создавать кастомные эффекты анимации, изменение стиля элементов или синхронизацию состояния интерфейса с сервером.
После того как цель обмена определена, Swappable меняет
местоположение элементов в DOM, используя стандартные
методы insertBefore или replaceChild. При этом
исходный элемент и целевой элемент полностью меняются местами, сохраняя
все атрибуты и обработчики событий.
swappable.on('swappable:swapped', (event) => {
// Можно обновить состояние приложения или синхронизировать данные
updateOrderInDatabase(event.source, event.over);
});
Важно: Swappable не создает копии элементов, а выполняет именно перемещение, поэтому любые привязанные события и данные сохраняются.
Swappable поддерживает дополнительные опции:
draggable — селектор перетаскиваемых
элементов.swapAnimation — позволяет включить
плавную анимацию обмена.delay — задержка перед началом
drag.mirror — настройка зеркала (размер,
класс, ограничения).const swappable = new Swappable('.container', {
draggable: '.item',
delay: 100,
mirror: { constrainDimensions: true },
swapAnimation: { duration: 300, easing: 'ease-in-out' }
});
Эти опции делают Swappable гибким инструментом для интерфейсов с динамическими сетками, списками или панелями.
Ключевое преимущество Swappable — интуитивно понятный обмен элементов без дублирования DOM и с поддержкой всех событий drag-and-drop.