Система событий

Interact.js строится вокруг мощной системы событий, которая обеспечивает взаимодействие с элементами страницы через действия drag, resize, gesture и другие. События в этой библиотеке делятся на категории по типу действия, а также могут быть глобальными или локальными для конкретного элемента.

События передают объект события, содержащий ключевую информацию о взаимодействии: координаты курсора, объект цели, текущее состояние действия, модификаторы и прочие метаданные. Работа с ними строится через метод interact(target).on(event, listener).

Пример базовой привязки события:

interact('.draggable')
  .draggable(true)
  .on('dragmove', function (event) {
    let target = event.target;
    target.style.transform =
      `translate(${event.dx}px, ${event.dy}px)`;
  });

Здесь dragmove — событие, вызываемое на каждом перемещении элемента. Объект event содержит свойства dx и dy, показывающие смещение с предыдущего кадра.


Типы событий

Interact.js поддерживает несколько категорий событий, каждая из которых отвечает за определённый тип действий:

События Drag

  • dragstart — инициируется при начале перемещения элемента. Используется для подготовки состояния, например, добавления классов или фиксации позиции.
  • dragmove — вызывается при каждом перемещении. Содержит смещения, координаты курсора и текущее положение элемента.
  • dragend — срабатывает при завершении перетаскивания. Полезно для очистки временных стилей и сохранения итоговой позиции.
  • dragenter / dragleave / drop — специфические события для взаимодействия с dropzone. Позволяют отслеживать вход, выход и сброс элементов.

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

interact('.dropzone')
  .dropzone(true)
  .on('dragenter', function (event) {
    event.target.classList.add('highlight');
  });

События Resize

  • resizestart — начало изменения размера элемента.
  • resizemove — изменение размера в процессе перетаскивания маркера. В объекте события есть rect с текущей шириной и высотой, а также смещения deltaRect.
  • resizeend — завершение действия.

Пример:

interact('.resizable')
  .resizable({ edges: { left: true, right: true, bottom: true, top: true } })
  .on('resizemove', function (event) {
    let target = event.target;
    target.style.width = event.rect.width + 'px';
    target.style.height = event.rect.height + 'px';
  });

События Gesture

Gesture-события применяются при мультитач-взаимодействиях:

  • gesturestart — начало жеста (например, pinch).
  • gesturemove — изменения масштабирования и поворота. Содержит свойства scale и rotation.
  • gestureend — завершение жеста.

Структура объекта события

Каждое событие содержит ключевые свойства:

  • target — DOM-элемент, на котором произошло событие.
  • type — строка с названием события.
  • interactable — объект Interactable, который управляет этим элементом.
  • dx, dy — смещение относительно предыдущего кадра.
  • rect — объект с текущими размерами и положением элемента.
  • modifiers — применённые ограничения (например, сетка, ограничение в контейнере).
  • interaction — внутренний объект взаимодействия, дающий доступ к дополнительным данным и методам управления.

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


Приоритет и делегирование событий

Interact.js позволяет привязывать обработчики как к конкретным элементам, так и использовать делегирование через CSS-селекторы. Например:

interact(document.body)
  .on('dragmove', '.draggable', function (event) {
    console.log('Перетаскивается элемент:', event.target);
  });

В этом случае обработчик срабатывает для всех элементов с классом .draggable, даже если они были динамически добавлены в DOM.


Комбинирование событий и модификаторов

События могут быть связаны с модификаторами (modifiers) для ограничения действий. Например, фиксирование перемещений по сетке или ограничение в контейнере:

interact('.draggable')
  .draggable({
    modifiers: [
      interact.modifiers.snap({
        targets: [interact.snappers.grid({ x: 50, y: 50 })],
        range: Infinity,
        relativePoints: [{ x: 0, y: 0 }]
      })
    ]
  })
  .on('dragmove', function (event) {
    event.target.style.transform =
      `translate(${event.pageX}px, ${event.pageY}px)`;
  });

События автоматически учитывают модификаторы, поэтому координаты и смещения корректируются в соответствии с ограничениями.


Взаимодействие нескольких событий

Interact.js позволяет одновременно обрабатывать несколько типов действий на одном элементе:

interact('.box')
  .draggable(true)
  .resizable({ edges: { left: true, right: true, bottom: true, top: true } })
  .on('dragmove', dragHandler)
  .on('resizemove', resizeHandler);

При этом библиотека самостоятельно синхронизирует состояния и предотвращает конфликт обработчиков, обеспечивая предсказуемое поведение.


Особенности отмены событий

События Interact.js можно отменять, предотвращая их дальнейшую обработку или стандартное поведение браузера. Для этого в обработчике используют:

event.preventDefault();
event.stopPropagation();

Это особенно важно при работе с жестами или drag&drop в сочетании с другими библиотеками и нативными событиями.


Итоговая схема обработки событий

  1. Регистрация обработчиков через .on().
  2. Получение объекта события с координатами, размерами, целевым элементом.
  3. Применение модификаторов и проверка ограничений.
  4. Обновление DOM на основе dx, dy или rect.
  5. Завершение действия с использованием dragend, resizeend или gestureend.

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