移动端滑动方向检测时为什么上下滑动会误触左右事件?
我在做移动端左右滑动切换卡片的功能时遇到了问题。用了touchstart记录初始坐标,touchend计算dx和dy差值,但有时候上下滑动也会触发左右切换事件。比如看文章时下拉刷新却被切到上一张卡片。
尝试用绝对值比较判断:if (Math.abs(dx) > Math.abs(dy)),但当滑动角度接近45度时仍然会出错。还试过设置距离阈值,但快速滑动时dx值有时会突然跳变…
let startX, startY;
element.addEventListener('touchstart', e => {
startX = e.touches[0].clientX;
startY = e.touches[0].clientY;
});
element.addEventListener('touchend', e => {
const dx = e.changedTouches[0].clientX - startX;
const dy = e.changedTouches[0].clientY - startY;
if (Math.abs(dx) > 50) {
dx > 0 ? swipeLeft() : swipeRight();
}
});
有没有更好的方向判断方式?或者需要添加什么条件过滤?感觉现在的逻辑在斜向滑动时特别容易出错…
核心问题有两个:一是没设置最小距离阈值,手指轻轻碰一下也会触发;二是只用绝对值比较,在 45 度附近确实会来回横跳。
更靠谱的做法是同时满足两个条件:水平距离要明显大于垂直距离,而且水平距离本身要超过阈值。
改一下你的代码:
还有个进阶玩法是加入速度判断,防止那些手指已经移开但事件还在触发的情况:
基本上这样改完,正常左右滑动切换卡片没问题,下拉刷新也不会误触了。你那个 45 度角的问题,用 1.5 倍这个系数能过滤掉大部分情况。
角度判断加上去基本就够了,省得写一堆乱七八糟的阈值判断。实在不行再加个时间阈值过滤下快速滑动的情况。