В библиотеке Shopify Draggable сенсоры ввода (input sensors) представляют собой механизм абстракции источников взаимодействия пользователя с интерфейсом. Сенсоры определяют, каким образом библиотека будет отслеживать события начала перетаскивания, его движение и завершение. Они отделяют логическую модель перетаскивания от конкретного устройства ввода, будь то мышь, касание на сенсорном экране или клавиатура.
MouseSensor Сенсор мыши отвечает за стандартное
взаимодействие через события mousedown,
mousemove и mouseup. Он обеспечивает плавное
перетаскивание элементов на десктопных устройствах и является базовым
сенсором для большинства приложений.
Ключевые особенности:
drag:start, drag:move,
drag:stop).TouchSensor Сенсор касаний предназначен для
мобильных устройств. Он работает с событиями touchstart,
touchmove, touchend и учитывает особенности
тач-интерфейсов, включая множественные касания.
Особенности реализации:
ForceTouchSensor / PointerSensor В современных
версиях Draggable введены сенсоры, использующие API указателя
(Pointer Events). Они объединяют поддержку мыши, касаний и
стилуса в одном интерфейсе. Это позволяет:
pointerdown), вместо
множества событий.Сенсоры реализованы как отдельные классы, наследующиеся от BaseSensor. Каждому сенсору необходимо реализовать минимальный набор методов:
attach() — подключение слушателей
событий к DOM-элементам. Обычно вызывается при инициализации
Draggable.detach() — удаление слушателей для
предотвращения утечек памяти.start(event) — логика начала
перетаскивания на основании события пользователя.move(event) — логика движения
элемента.stop(event) — завершение
перетаскивания.Ключевая идея архитектуры: сенсор не знает о структуре Draggable и не взаимодействует с DOM напрямую. Он генерирует события, которые библиотека интерпретирует для обновления позиции элементов.
При создании экземпляра Draggable можно указать массив сенсоров:
import { Draggable, MouseSensor, TouchSensor } from '@shopify/draggable';
const draggable = new Draggable(document.querySelectorAll('.draggable-item'), {
sensors: [MouseSensor, TouchSensor],
draggable: '.draggable-item'
});
Пояснения к настройке:
sensors — массив классов сенсоров.
Порядок важен: первый сенсор получает приоритет при инициализации.Draggable использует CustomEvent-подход. Сенсоры
генерируют события с типами drag:start,
drag:move, drag:stop, которые можно
слушать:
draggable.on('drag:start', (event) => {
console.log('Начало перетаскивания:', event.source);
});
draggable.on('drag:move', (event) => {
event.source.style.transform = `translate(${event.delta.x}px, ${event.delta.y}px)`;
});
draggable.on('drag:stop', (event) => {
console.log('Перетаскивание завершено');
});
Особенности передачи данных:
event.source — DOM-элемент, с которого началось
перетаскивание.event.sensorEvent — оригинальное событие
(MouseEvent, TouchEvent,
PointerEvent), обеспечивающее доступ к координатам и
дополнительной информации.event.delta — разница между начальной и текущей
позицией курсора.Можно создавать собственные сенсоры, расширяя BaseSensor:
import { BaseSensor } from '@shopify/draggable';
class CustomSensor extends BaseSensor {
attach() {
this.el.addEventListener('mousedown', this.start);
}
start(event) {
console.log('Custom drag start');
super.start(event);
}
}
Возможности кастомных сенсоров:
Сенсоры могут быть расширены плагинами для:
Пример использования сенсора с плагином:
import { Sortable } from '@shopify/draggable';
const sortable = new Sortable(document.querySelectorAll('.list-item'), {
sensors: [MouseSensor, TouchSensor],
draggable: '.list-item'
});
В этом случае сенсор передает события плагину, который отвечает за перестановку элементов в DOM, а сенсор остается «чистым» и независимым от конкретной логики сортировки.
Такой подход обеспечивает гибкость, масштабируемость и легкость поддержки различных типов устройств ввода без изменения ядра библиотеки. Сенсоры вводят уровень абстракции, позволяя отделять обработку низкоуровневых событий от бизнес-логики интерфейса.