MouseSensor

MouseSensor — это встроенный сенсор библиотеки Shopify Draggable, отвечающий за взаимодействие с элементами через мышь. Он обеспечивает отслеживание событий mousedown, mousemove и mouseup, превращая обычные DOM-элементы в перетаскиваемые объекты.

Основное предназначение MouseSensor — детекция начала и конца перетаскивания, а также вычисление смещения курсора относительно исходной позиции элемента. Этот сенсор является базовым для создания интерактивных списков, карточек или сеток с drag-and-drop функциональностью.


Инициализация MouseSensor

Подключение сенсора к Draggable происходит через массив сенсоров при создании экземпляра:

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

const container = document.querySelector('.draggable-container');

const draggable = new Draggable(container, {
  draggable: '.draggable-item',
  sensors: [MouseSensor]
});

Ключевой момент: sensors принимает массив классов сенсоров, что позволяет комбинировать MouseSensor с TouchSensor или другими сенсорами для поддержки разных устройств.


Основные события MouseSensor

MouseSensor генерирует ряд событий, которые можно использовать для управления логикой перетаскивания:

  1. drag:start — срабатывает при начале перетаскивания элемента.
  2. drag:move — срабатывает при перемещении курсора мыши вместе с элементом.
  3. drag:stop — фиксирует момент завершения перетаскивания.
  4. drag:over / drag:out — события, возникающие при наведении элемента на потенциальный контейнер или его покидании.

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

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

draggable.on('drag:move', (event) => {
  console.log('Перемещение элемента', event.sensorEvent.clientX, event.sensorEvent.clientY);
});

draggable.on('drag:stop', (event) => {
  console.log('Элемент отпущен', event.source);
});

Настройка поведения MouseSensor

MouseSensor позволяет конфигурировать чувствительность и условия активации через опции сенсора. Основные параметры:

  • activationConstraint — объект, задающий условия начала перетаскивания. Например:
const draggable = new Draggable(container, {
  draggable: '.draggable-item',
  sensors: [MouseSensor],
  mouseSensor: {
    activationConstraint: {
      distance: 10  // перетаскивание начинается после смещения на 10px
    }
  }
});
  • scroll — флаг, указывающий, будет ли сенсор автоматически скроллить контейнер при перетаскивании элемента к границам:
mouseSensor: {
  scroll: true
}
  • delay — задает задержку перед активацией перетаскивания (в миллисекундах). Полезно для предотвращения случайных перемещений при клике.

Внутренние методы MouseSensor

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

  1. attach() / detach() — подключение и отключение обработчиков событий mousedown, mousemove и mouseup.
  2. start(event) — проверка условия активации и начало перетаскивания.
  3. move(event) — обновление позиции элемента в соответствии с перемещением мыши.
  4. stop(event) — завершение процесса перетаскивания, очистка временных данных.

Эти методы можно переопределять при наследовании собственного сенсора, если требуется кастомная логика перетаскивания.


Ограничение области перетаскивания

MouseSensor поддерживает возможность ограничения движения элемента по определённой оси:

draggable.on('drag:move', (event) => {
  const el = event.source;
  // Ограничение по оси X
  el.style.transform = `translateX(${event.sensorEvent.clientX}px)`;
});

Также можно использовать activationConstraint для ограничения минимального смещения, предотвращая случайные срабатывания.


Сочетание MouseSensor с другими сенсорами

Для обеспечения работы на сенсорных устройствах MouseSensor часто комбинируют с TouchSensor:

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

const draggable = new Draggable(container, {
  draggable: '.draggable-item',
  sensors: [MouseSensor, TouchSensor]
});

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


Производительность и оптимизация

MouseSensor оптимизирован для работы с большим количеством элементов, однако при сложных интерфейсах рекомендуется:

  • Использовать делегирование событий на контейнере.
  • Ограничивать количество обновлений DOM через requestAnimationFrame.
  • Применять activationConstraint.distance и delay для уменьшения ложных срабатываний.

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


Практические сценарии использования

  1. Сортируемые списки — с помощью MouseSensor можно перетаскивать карточки или строки таблицы.
  2. Drag-and-drop панели — реализация интерфейса с перемещением виджетов.
  3. Интерактивные сетки — динамическое изменение порядка элементов без перезагрузки страницы.

MouseSensor обеспечивает точный контроль над всеми аспектами перемещения элементов мышью, делая интерфейсы более живыми и интерактивными.