targetTouches 在多指触摸时怎么获取正确的手指信息?

W″金宇 阅读 22

我在做移动端的手势缩放功能,监听 touchmove 事件时想通过 event.targetTouches 获取当前接触屏幕的手指列表,但发现有时候拿到的数组长度和实际触摸的手指数对不上,这是为啥?

比如我用两根手指在图片上缩放,打印出来却是3个 Touch 对象。我试过用 changedTouches 也不太对。下面是我的监听代码:

element.addEventListener('touchmove', (e) => {
  console.log('targetTouches length:', e.targetTouches.length);
  for (let i = 0; i < e.targetTouches.length; i++) {
    console.log('Touch ID:', e.targetTouches[i].identifier);
  }
});
我来解答 赞 4 收藏
二维码
手机扫码查看
2 条解答
博主朝阳
问题在于 targetTouches 只返回在当前事件目标元素上的触摸点,如果手指从其他区域滑入或者事件目标变化了,计数就会乱。

直接改用 touches 获取屏幕上所有触摸点:

element.addEventListener('touchmove', (e) => {  console.log('touches length:', e.touches.length);
for (let i = 0; i < e.touches.length; i++) {
console.log('Touch ID:', e.touches[i].identifier);
}
});


如果你的缩放元素会冒泡到父元素,再加个 preventDefault 阻止默认行为和冒泡,防止计数重复。
点赞
2026-03-11 23:08
爱学习的浩迪
问题在于 targetTouches 统计的是当前事件目标元素上的触摸,不是全屏所有手指。

你用两根手指在图片上缩放,其中一根手指如果移出了图片区域或者从图片外开始滑动,targetTouches 就不会包含它。反过来,如果第三根手指按在了图片上但没动,也会算进去。

想要准确获取当前正在交互的手指,用 changedTouches 更合适:

element.addEventListener('touchmove', (e) => {
// changedTouches 包含当前事件中位置发生变化的所有手指
console.log('changedTouches length:', e.changedTouches.length);

// 缩放逻辑只需要关注当前在动的手指
if (e.changedTouches.length === 2) {
const touch1 = e.changedTouches[0];
const touch2 = e.changedTouches[1];

// 计算两指距离
const distance = Math.hypot(
touch2.clientX - touch1.clientX,
touch2.clientY - touch1.clientY
);

// 对比上次的距离来计算缩放比例
}
});


另外如果你的场景是跨元素滑动(比如从图片划到空白处),建议在 touchstart 时用 touches 记录初始状态,然后在 touchmove 里用 changedTouches 追踪变化的手指 ID,这样逻辑更清晰。

还有个小坑:touchmove 事件里 changedTouches 不一定总是包含全部手指,有些浏览器只返回位置变化的那一根,最好自己维护一个 activeTouches 字典,按 identifier 存着。
点赞
2026-03-11 03:00