移动端手势滑动时页面跟着滚动怎么解决?

Designer°国娟 阅读 71

我在开发一个支持左右滑动切换卡片的移动端页面,用touchstart和touchmove事件检测手势位移,但发现当手指滑动距离较大时页面会跟着滚动,导致手势识别不准。试过在touchmove里加e.preventDefault(),但这样完全阻止滚动后又无法正常上下滚动页面了。

代码大概是这样的:


let startX;
element.addEventListener('touchstart', (e) => {
  startX = e.touches[0].clientX;
});
element.addEventListener('touchmove', (e) => {
  const currentX = e.touches[0].clientX;
  const distance = startX - currentX;
  // 这里想根据distance触发滑动效果,但页面还是在滚动
});

有什么办法既能检测水平滑动手势,又不影响页面垂直方向的正常滚动呢?

我来解答 赞 9 收藏
二维码
手机扫码查看
2 条解答
设计师云碧
判断手指移动方向,只在水平滑动时阻止默认行为就行。记录touchstart的Y坐标,和touchmove时的Y坐标对比,如果X方向位移比Y方向大,就说明是横向滑动,这时候才preventDefault。

let startX, startY;
element.addEventListener('touchstart', (e) => {
startX = e.touches[0].clientX;
startY = e.touches[0].clientY;
});

element.addEventListener('touchmove', (e) => {
const currentX = e.touches[0].clientX;
const currentY = e.touches[0].clientY;

const deltaX = Math.abs(startX - currentX);
const deltaY = Math.abs(startY - currentY);

// 水平移动距离大于垂直距离时,才阻止默认滚动
if (deltaX > deltaY) {
e.preventDefault();
}
}, { passive: false });


关键是touchmove事件监听器加上 { passive: false } ,否则preventDefault会无效。
点赞
2026-03-13 10:11
Zz张豪
Zz张豪 Lv1
只在水平滑动时阻止默认行为。
element.addEventListener('touchmove', (e) => {
const dx = Math.abs(e.touches[0].clientX - startX);
const dy = Math.abs(e.touches[0].clientY - startY);
if (dx > dy) e.preventDefault(); // 水平为主,阻止滚动
});

就这样。
点赞 2
2026-02-12 09:11