Lifecycle hooks

В библиотеке Shopify Draggable жизненный цикл элементов управления перетаскиванием управляется через механизм lifecycle hooks. Эти хуки позволяют реагировать на ключевые события, возникающие в процессе инициализации, перетаскивания и завершения работы элементов. Они обеспечивают гибкий контроль и позволяют расширять поведение draggable объектов без модификации исходного кода библиотеки.


Основные хуки жизненного цикла

В Draggable определены следующие типы хуков:

  1. initialize – вызывается при создании экземпляра Draggable, перед тем как элементы станут интерактивными. Используется для настройки начальных параметров, регистрации слушателей или модификации DOM.

  2. drag:start – срабатывает в момент начала перетаскивания. На этом этапе можно зафиксировать начальные координаты элемента, изменить стиль курсора, применить визуальные эффекты, или подготовить связанные данные.

  3. drag:move – вызывается при каждом изменении позиции элемента во время перетаскивания. Позволяет отслеживать координаты, обновлять позиции других элементов, синхронизировать данные с backend или визуализировать динамическое смещение.

  4. drag:stop – активируется после завершения перетаскивания. Здесь обычно применяются действия по финализации: сброс временных стилей, сохранение новых координат в базу данных, анимация возвращения элемента в исходное положение при отмене операции.

  5. sortable:sorted – специфичный для сортируемых списков хук, срабатывающий после того как элемент успешно поменял свое место среди других. Используется для обновления индексов элементов, отправки данных на сервер или запуска дополнительной логики сортировки.

  6. destroy – вызывается при удалении экземпляра Draggable. Позволяет очищать ресурсы, удалять слушателей событий и предотвращать утечки памяти.


Подключение хуков

Хуки регистрируются через метод on экземпляра Draggable. Синтаксис прост и последовательный:

import { Draggable } from '@shopify/draggable';

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

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

draggable.on('drag:move', (event) => {
  event.source.style.background = 'rgba(0, 123, 255, 0.2)';
});

draggable.on('drag:stop', (event) => {
  event.source.style.background = '';
});

Ключевой момент: event.source всегда содержит исходный DOM-элемент, который перемещается. Объект события также предоставляет sensorEvent, mirror, originalSource и другие полезные свойства для расширенной обработки.


Манипуляции с зеркалом (mirror)

Когда элемент перетаскивается, Draggable создаёт mirror — визуальную копию элемента, которая следует за курсором. Хуки жизненного цикла позволяют управлять mirror:

  • На drag:start можно изменить стиль mirror: цвет, прозрачность, тень.
  • На drag:move возможно динамическое изменение размеров или трансформаций.
  • На drag:stop mirror автоматически удаляется, но можно вручную анимировать его возвращение.
draggable.on('drag:start', (event) => {
  event.mirror.style.boxShadow = '0 4px 12px rgba(0,0,0,0.2)';
});

Использование хуков для сортировки

В sortable списках жизненный цикл элементов расширяется дополнительными хуками:

  • sortable:sort – срабатывает при перемещении элемента внутри контейнера до фиксации позиции.
  • sortable:sorted – срабатывает после фактического изменения позиции элемента.
  • sortable:stop – вызывается после окончания сортировки, когда элементы вернулись в новое положение.
draggable.on('sortable:sorted', (event) => {
  const sortedElements = Array.from(event.container.children);
  sortedElements.forEach((el, index) => {
    el.dataset.index = index;
  });
});

Эти хуки обеспечивают синхронизацию индексов и позволяют обновлять порядок элементов в базе данных или локальном состоянии.


Практические рекомендации

  • Для оптимизации производительности обработку drag:move следует минимизировать: лучше изменять классы и стили через requestAnimationFrame.
  • Для комплексных интерфейсов использовать комбинацию хуков drag:start, drag:move и drag:stop для плавных анимаций и обратной связи.
  • Хуки initialize и destroy подходят для подготовки и очистки DOM и данных, что предотвращает утечки памяти.
  • Всегда учитывать, что mirror и исходный элемент различны: манипуляции mirror не затрагивают source до завершения перетаскивания.

Расширение функциональности через кастомные хуки

Draggable позволяет создавать собственные события, которые интегрируются с lifecycle. Это удобно для построения сложных интерфейсов с несколькими drag-сценариями.

draggable.on('custom:highlight', (event) => {
  event.source.classList.add('highlight');
});

Такой подход обеспечивает модульность и отделяет логику перетаскивания от бизнес-логики.


Важные свойства объектов событий

Каждый хук получает объект события с набором свойств:

  • source – исходный элемент.
  • originalSource – элемент, с которого началось перетаскивание.
  • mirror – копия, следящая за курсором.
  • sensorEvent – нативное событие мыши или касания.
  • container – родительский контейнер draggable.

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


Lifecycle hooks в Shopify Draggable являются основой для точного контроля над перетаскиванием и сортировкой элементов. Грамотное использование хуков позволяет создавать плавные, отзывчивые и модульные интерфейсы с полным контролем над поведением draggable объектов.