Типы и интерфейсы

Библиотека Shopify Draggable построена вокруг концепции перетаскиваемых элементов и предоставляет гибкие интерфейсы для управления взаимодействием пользователя с DOM. В основе лежат Drag, Sortable, Swappable и Droppable, каждый из которых реализует определённый тип поведения и событийную модель.


Класс Draggable

Draggable — это базовый класс, который создаёт экземпляр перетаскиваемого интерфейса. Его можно использовать напрямую или через наследуемые классы для более специфичных случаев.

Конструктор:

new Draggable(el, options)

Параметры:

  • el — CSS-селектор или NodeList элементов, которые будут перетаскиваемыми.

  • options — объект конфигурации с ключевыми свойствами:

    • draggable — селектор внутри контейнера, определяющий перетаскиваемый элемент.
    • delay — задержка перед активацией drag (ms).
    • mirror — создание зеркального элемента при перетаскивании.
    • handle — селектор для элементов, через которые активируется перетаскивание.

Ключевые методы:

  • .on(eventName, callback) — регистрация обработчика событий (drag:start, drag:move, drag:stop и др.).
  • .off(eventName, callback) — удаление обработчика.
  • .destroy() — уничтожение экземпляра и всех слушателей.

Пример использования:

const draggable = new Draggable(document.querySelectorAll('.item'), {
  draggable: '.item',
  delay: 100
});

draggable.on('drag:start', event => {
  console.log('Начато перетаскивание', event.source);
});

Интерфейс Sortable

Sortable расширяет Draggable и позволяет менять порядок элементов внутри контейнера.

Особенности:

  • Поддержка множественных контейнеров.

  • События:

    • sortable:sort
    • sortable:sorted
    • sortable:stop
  • Позволяет задать swapAnimation, чтобы элементы анимированно перемещались при перестановке.

Пример конфигурации:

const sortable = new Sortable(document.querySelectorAll('.list'), {
  draggable: '.list-item',
  mirror: {
    constrainDimensions: true
  }
});

sortable.on('sortable:sorted', event => {
  console.log('Элемент перемещён', event.oldIndex, '→', event.newIndex);
});

Интерфейс Swappable

Swappable реализует возможность обмена местами элементов между контейнерами или внутри одного контейнера без полного сортирования списка.

Основные свойства:

  • containers — список контейнеров, между которыми разрешён обмен.

  • swapAnimation — включает анимацию перемещения элементов.

  • События:

    • swappable:swapped
    • swappable:start
    • swappable:stop

Пример:

const swappable = new Swappable([container1, container2], {
  draggable: '.card'
});

swappable.on('swappable:swapped', event => {
  console.log('Элементы поменялись местами', event.source, event.over);
});

Интерфейс Droppable

Droppable предоставляет возможность реагировать на выбрасывание элементов на определённые зоны.

Конфигурация:

  • containers — DOM-элементы, на которые можно бросать.

  • acceptFrom — селектор или функция для фильтрации допустимых элементов.

  • События:

    • droppable:over
    • droppable:out
    • droppable:dropped

Пример:

const droppable = new Droppable(document.querySelectorAll('.drop-zone'), {
  draggable: '.draggable-item'
});

droppable.on('droppable:dropped', event => {
  console.log('Элемент сброшен в зону', event.over);
});

Типы событий и интерфейсы

Все классы библиотеки используют единый подход к событиям:

Событие Описание
drag:start Начало перетаскивания элемента
drag:move Перемещение элемента во время drag
drag:stop Завершение перетаскивания
sortable:sorted Элемент успешно перемещён в новый индекс
swappable:swapped Элементы поменялись местами
droppable:dropped Элемент был сброшен на допустимую зону

Каждое событие передаёт объект event с ключевыми свойствами:

  • source — исходный элемент.
  • over — элемент, над которым находится перетаскиваемый объект.
  • container — контейнер, к которому принадлежит элемент.
  • oldIndex / newIndex — индексы в списке (для сортировки).

Настройка интерфейсов через опции

Общие опции:

  • mirror — объект для настройки зеркального элемента:

    • constrainDimensions — сохранять размеры оригинала.
    • xAxis / yAxis — ограничение движения по осям.
  • delay — задержка перед активацией.

  • handle — элементы, через которые разрешено перетаскивание.

  • classes — кастомизация CSS классов для состояний: mirror, dragging, over, sortable-mirror.

Пример комбинированной конфигурации:

const sortable = new Sortable(document.querySelectorAll('.list'), {
  draggable: '.item',
  handle: '.drag-handle',
  mirror: {
    constrainDimensions: true
  },
  classes: {
    mirror: 'custom-mirror',
    dragging: 'custom-dragging'
  }
});

Работа с контейнерами

Контейнеры являются ключевым элементом интерфейсов Sortable, Swappable и Droppable. Каждый контейнер отслеживает:

  • Состояние перетаскиваемых элементов.
  • Разрешённые элементы для операций.
  • Подключённые события и их обработчики.

Контейнеры можно комбинировать, создавать группы и динамически добавлять или удалять из Draggable-экземпляра.


Интерфейс Mirror

Зеркальный элемент создаётся автоматически при перетаскивании. Основные свойства:

  • source — оригинальный элемент.
  • mirror — DOM-элемент, который визуально повторяет source.
  • translate — текущие координаты смещения по осям.
  • destroy() — удаление зеркала.
draggable.on('drag:start', event => {
  const mirror = event.mirror;
  mirror.classList.add('highlight');
});

Кастомизация и расширение интерфейсов

Shopify Draggable поддерживает:

  • Добавление кастомных событий через .trigger().
  • Подключение модулей расширений (например, auto-scroll, sortable animation).
  • Создание собственных обработчиков для сложных сценариев: ограничение по оси, snap-to-grid, динамическое разрешение контейнеров.