DragSensor

DragSensor — это базовый класс сенсоров в библиотеке Shopify Draggable, который отвечает за отслеживание пользовательских действий, инициирующих перетаскивание элементов. Сенсоры являются связующим звеном между событиями ввода (мышь, касание, клавиатура) и системой перетаскивания, позволяя Draggable реагировать на интерактивные действия пользователя.


Основные свойства и методы DragSensor

  • constructor(draggable, options) Конструктор принимает два аргумента:

    1. draggable — экземпляр класса Draggable, для которого создаётся сенсор.
    2. options — объект настроек, специфичный для сенсора. Настройки обычно включают порог срабатывания (например, минимальное смещение курсора для начала перетаскивания).
  • attach() Метод привязывает сенсор к DOM-элементам, подписываясь на события пользовательского ввода. Для MouseSensor это будут события mousedown и mousemove, для TouchSensortouchstart и touchmove.

  • detach() Метод отключает сенсор, удаляя обработчики событий. Используется при уничтожении Draggable или временном отключении перетаскивания.

  • start(event) Инициализация процесса перетаскивания. Вызывается, когда пользователь начинает взаимодействовать с элементом (например, при нажатии кнопки мыши). В методе обычно выполняется:

    • проверка, можно ли начать перетаскивание (canStart)
    • фиксация начальных координат
    • генерация события drag:start через Draggable.
  • move(event) Обработка перемещения курсора или касания во время активного перетаскивания. Обычно вызывается из обработчиков mousemove или touchmove. Отвечает за обновление координат и распространение события drag:move.

  • stop(event) Завершение перетаскивания. В этом методе происходит:

    • очистка временных данных
    • генерация события drag:stop
    • отключение визуальных индикаторов перетаскивания.

Взаимодействие с Draggable

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

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

  2. События Draggable Сенсор служит триггером для стандартных событий Draggable:

    • drag:start — начало перетаскивания
    • drag:move — движение элемента
    • drag:stop — завершение перетаскивания
    • drag:over и drag:out — взаимодействие с контейнерами Все эти события создаются и эмитируются сенсором через Draggable.

Настройка порога срабатывания

Одной из ключевых настроек DragSensor является distance — минимальное смещение курсора, необходимое для активации перетаскивания. Это предотвращает случайные срабатывания при лёгких кликах или касаниях.

Пример настройки:

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

const draggable = new Draggable(document.querySelectorAll('.draggable-item'), {
  draggable: '.item',
  sensors: [
    {
      sensor: MouseSensor,
      options: {
        distance: 10
      }
    }
  ]
});

В этом примере MouseSensor не начнёт перетаскивание, пока курсор не сдвинется на 10 пикселей от исходной точки нажатия.


Создание кастомного сенсора

DragSensor можно расширять для реализации нестандартных источников ввода. Для этого создаётся класс-наследник, реализующий методы attach, detach, start, move и stop.

Пример кастомного сенсора:

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

class CustomSensor extends DragSensor {
  attach() {
    this.handleEvent = this.handleEvent.bind(this);
    document.addEventListener('pointerdown', this.handleEvent);
  }

  detach() {
    document.removeEventListener('pointerdown', this.handleEvent);
  }

  handleEvent(event) {
    if (this.canStart(event)) {
      this.start(event);
    }
  }

  start(event) {
    super.start(event);
    console.log('Custom drag started');
  }

  move(event) {
    super.move(event);
    console.log('Custom drag moved');
  }

  stop(event) {
    super.stop(event);
    console.log('Custom drag stopped');
  }
}

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


Важные нюансы использования

  • События сенсора должны быть чистыми: отключение всех обработчиков в detach критично для предотвращения утечек памяти.
  • Оптимизация частоты вызова move: при интенсивных событиях ввода (например, mousemove) рекомендуется использовать requestAnimationFrame или throttle для снижения нагрузки на рендер.
  • Совместимость сенсоров: при подключении нескольких сенсоров важно корректно обрабатывать приоритет и предотвращать дублирование событий.

Поддерживаемые сенсоры на базе DragSensor

  • MouseSensor — для мыши
  • TouchSensor — для сенсорных экранов
  • Sensor с клавиатурным управлением — экспериментальный вариант для accessibility
  • Любой кастомный сенсор, расширяющий DragSensor

Все они наследуют общую логику start, move и stop, что обеспечивает единообразное поведение Draggable независимо от источника ввода.


Итоговая структура DragSensor

  1. Инициализация через конструктор
  2. Привязка событий через attach
  3. Обработка начала перетаскивания в start
  4. Обновление позиции элемента в move
  5. Завершение перетаскивания и очистка ресурсов в stop
  6. Отключение сенсора через detach

Такое разделение ответственности обеспечивает модульность и гибкость всей библиотеки Shopify Draggable, делая DragSensor ключевым элементом для расширяемости и поддержки различных устройств ввода.