Mithril — лёгкий и быстрый JavaScript-фреймворк для создания одностраничных приложений (SPA), который предоставляет удобный механизм для работы с событиями, включая touch-события на мобильных устройствах. В отличие от стандартных DOM-манипуляций, Mithril позволяет организовать обработку событий через виртуальный DOM, что упрощает управление состоянием компонентов и повышает производительность.
На мобильных устройствах браузеры поддерживают следующие основные события касания:
touchstart — срабатывает в момент начала касания
экрана.touchmove — срабатывает при движении пальца по
экрану.touchend — срабатывает при окончании касания.touchcancel — срабатывает, если касание прерывается
системой (например, при входящем звонке).Каждое событие предоставляет объект события TouchEvent,
который содержит следующие важные свойства:
touches — список всех активных касаний на экране.targetTouches — список касаний, находящихся на
конкретном элементе.changedTouches — список касаний, изменившихся в текущем
событии.Эти свойства позволяют точно отслеживать положение пальцев и реализовывать сложные жесты.
В Mithril события обрабатываются через объект
vnode.attrs, передаваемый в функцию создания элемента
m(). Привязка touch-событий аналогична обычным
DOM-событиям:
const TouchComponent = {
view: () => m('div.touch-area', {
ontouchstart: (e) => console.log('Касание началось', e.touches),
ontouchmove: (e) => console.log('Движение пальца', e.touches),
ontouchend: (e) => console.log('Касание завершено', e.changedTouches)
}, 'Тестовая зона для touch-событий')
};
Особенности:
ontouch* в объекте
атрибутов.e.preventDefault() и e.stopPropagation()
работают так же, как в обычном DOM, и позволяют управлять поведением
прокрутки или всплытием событий.Для распознавания свайпа необходимо отслеживать начальные и конечные координаты касания:
const SwipeComponent = {
startX: 0,
startY: 0,
view: () => m('div.swipe-area', {
ontouchstart: (e) => {
const touch = e.touches[0];
SwipeComponent.startX = touch.clientX;
SwipeComponent.startY = touch.clientY;
},
ontouchend: (e) => {
const touch = e.changedTouches[0];
const dx = touch.clientX - SwipeComponent.startX;
const dy = touch.clientY - SwipeComponent.startY;
if (Math.abs(dx) > 50 && Math.abs(dy) < 30) {
console.log(dx > 0 ? 'Свайп вправо' : 'Свайп влево');
}
}
}, 'Свайп-зона')
};
Ключевые моменты:
changedTouches[0] гарантирует корректное получение
касания, которое завершилось.dx > 50) помогает отличить
случайные движения от намеренных свайпов.dy) учитывается для фильтрации
ложных срабатываний.Для обработки мультитач-событий необходимо использовать
touches:
const PinchComponent = {
initialDistance: 0,
view: () => m('div.pinch-area', {
ontouchstart: (e) => {
if (e.touches.length === 2) {
const [t1, t2] = e.touches;
PinchComponent.initialDistance = Math.hypot(t2.clientX - t1.clientX, t2.clientY - t1.clientY);
}
},
ontouchmove: (e) => {
if (e.touches.length === 2) {
const [t1, t2] = e.touches;
const currentDistance = Math.hypot(t2.clientX - t1.clientX, t2.clientY - t1.clientY);
const scale = currentDistance / PinchComponent.initialDistance;
console.log('Масштабирование:', scale);
}
}
}, 'Зона для пинч-зум')
};
Особенности:
Math.hypot позволяет вычислить расстояние между двумя
касаниями.{ passive: true } для событий touchmove, если
не требуется preventDefault(), чтобы избежать проблем с
производительностью при скролле.touchmove лучше обрабатывать через троттлинг, чтобы снизить
нагрузку на UI.Mithril можно комбинировать с библиотеками распознавания жестов, такими как Hammer.js, через обычные события:
m('div', {
oncreate: (vnode) => {
const hammer = new Hammer(vnode.dom);
hammer.on('swipeleft', () => console.log('Свайп влево через Hammer.js'));
}
});
Такой подход позволяет использовать мощные возможности распознавания жестов без изменения архитектуры компонентов Mithril.
Работа с touch-событиями в Mithril предоставляет гибкий и производительный механизм управления интерактивностью на мобильных устройствах, сохраняя при этом простоту виртуального DOM и декларативного подхода к созданию интерфейсов.