原生触摸手势处理需状态管理+坐标计算+行为拦截,关键三步:touchstart记起点坐标与时间戳,touchmove用changedtouches追踪移动,touchend依位移/耗时/方向判定手势并清空状态;必调preventdefault并配touch-action优化。

直接用原生 touchstart、touchmove、touchend 处理手势,核心是状态管理 + 坐标计算 + 行为拦截,不是简单监听事件就能出效果。
关键三步:记录起点、持续追踪、判断意图
手势识别本质是“从一串坐标变化中还原用户意图”。比如滑动,要靠起始点和结束点的位移差;缩放则依赖两指距离变化。不维护状态,每次 touchmove 都是孤立数据。
- touchstart 中取 e.targetTouches[0](推荐)或 e.touches[0] 记录初始坐标(clientX/clientY),同时存时间戳用于速度判断
- touchmove 中用 e.changedTouches[0] 获取本次移动的触点,避免因多指干扰导致坐标错乱
- touchend 中对比位移、耗时、方向,决定触发 tap、swipe 还是 cancel;别忘了清空临时变量,否则下次手势可能误继承上一次状态
必须加 preventDefault,否则手势会失效
浏览器对触摸有默认行为:单指拖拽可能触发页面滚动,双指可能触发缩放。只要你的逻辑需要接管交互,就必须在 touchstart 和 touchmove 里调用 event.preventDefault()。
- 只在目标元素上加,不要盲目给 document 绑定,否则会影响全局滚动
- 如果同时支持鼠标和触摸(如 PC 调试),可用 event.cancelable && event.preventDefault() 做安全判断
- 配合 CSS 的 touch-action: none(禁用浏览器默认手势)或 touch-action: pan-x pan-y(仅允许指定方向滚动),能显著提升响应精度
多指手势要区分三个触点列表
touches、targetTouches、changedTouches 容易混淆,但分工明确:
- targetTouches:当前绑定事件的元素上的所有手指 —— 最常用,适合单指拖拽、双指缩放等场景
- changedTouches:本次事件(如某次 touchmove)中状态发生变化的手指 —— 判断哪根手指刚抬起或按下,尤其在多指中途离开时关键
- touches:屏幕上全部手指 —— 少用,除非做全局手势(如三指上滑唤出控制中心)
- 双指缩放示例:touchstart 时用 targetTouches 计算两指初始距离和中心点;touchmove 时仍用 targetTouches 获取实时两指位置,再算新距离和新中心,结合 scale 和 translate 实现以中心缩放
性能与体验细节不能漏
高频 touchmove 容易卡顿,且小位移抖动会导致误判,得做基础优化:
- 用 requestAnimationFrame 节流 touchmove 的处理逻辑,避免每帧都重算 transform
- 设置位移阈值(如 10px)和时间阈值(如 250ms),过滤掉轻点、悬停、抖动等无效操作
- 注意 pageX/clientX/screenX 区别:clientX 是视口坐标,适合做相对位移;pageX 含滚动偏移,适合绝对定位类操作
- 别忘了 touchcancel 事件 —— 来电、弹窗、系统中断时触发,需清理状态,避免手势残留











