为什么移动端TouchEnd事件在快速滑动后不触发?

宇文晨晰 阅读 60

在移动端做卡片滑动交互时,发现当快速滑动手指离开屏幕后,TouchEnd事件偶尔不触发,导致卡片位置没及时更新。代码已经绑定了TouchEvent,但测试时发现:

尝试给卡片加了CSS过渡效果后问题更明显,比如这个样式:

.slide-card {
  transition: transform 0.2s;
  touch-action: pan-x;
}

用Chrome DevTools模拟触摸没问题,但真机测试时,特别是快速左右滑动后突然停住,事件监听器偶尔收不到TouchEnd。试过把transition改成will-change: transform也没解决,求大佬指点是哪里出问题了?

我来解答 赞 9 收藏
二维码
手机扫码查看
1 条解答
程序猿丹丹
这个问题我之前也遇到过,移动端的TouchEvent在快速滑动时确实容易丢事件。直接说解决方案吧:

别用 touchend 了,改用 touchcanceltouchend 一起监听。快速滑动时,系统经常会触发 touchcancel 而不是 touchend,特别是在有CSS过渡效果的情况下。

另外,把 passive 设置为 false,阻止浏览器默认行为,这样能减少事件丢失的概率。代码可以直接这么写:

const card = document.querySelector('.slide-card');

card.addEventListener('touchstart', handleTouchStart, { passive: false });
card.addEventListener('touchmove', handleTouchMove, { passive: false });
card.addEventListener('touchend', handleTouchEnd, { passive: false });
card.addEventListener('touchcancel', handleTouchCancel, { passive: false });

function handleTouchCancel(event) {
console.log('Touch cancelled');
// 在这里处理 touchend 的逻辑
}

function handleTouchEnd(event) {
console.log('Touch ended');
// 正常结束逻辑
}


记得在 handleTouchCancel 里也处理卡片位置更新的逻辑,不然快速滑动时位置会错乱。这种方式我已经在几个项目里用过了,基本能解决这个问题。

如果还是有问题,建议试试 PointerEvent,比 TouchEvent 稳定一些,不过兼容性要注意一下。
点赞 7
2026-01-31 17:18