Pan手势在移动端为啥没反应?

UX-艳青 阅读 15

我在用 Hammer.js 做一个滑动删除的功能,绑定了 pan 事件,但在手机上怎么划都没触发。本地开发时 Chrome 模拟器里是好的,真机测试就失效了。

查了文档说要启用 recognizeWith 和 requireFailure,也试了但还是不行。是不是还要处理 touch-action?我现在的元素样式是这样的:

.item {
  touch-action: none;
}

JS 初始化代码如下:

const mc = new Hammer(document.querySelector('.item'));
mc.get('pan').set({ direction: Hammer.DIRECTION_HORIZONTAL });
mc.on('pan', (e) => {
  console.log('panning', e.deltaX);
});

到底漏了哪一步啊?感觉快被这手势搞疯了……

我来解答 赞 5 收藏
二维码
手机扫码查看
1 条解答
俊美 ☘︎
你这问题我太熟悉了,当年我也被 Hammer.js 在移动端坑过无数次。
问题就出在 Hammer.js 默认会阻止浏览器的默认行为,尤其是滚动和缩放,但现代浏览器(特别是 iOS Safari)对 touch-action 的处理更严格,光写 touch-action: none; 不够,还得确保 Hammer 的配置和 CSS 配合到位。

你先试试在初始化的时候加上这一行:

mc.get('pan').set({ enable: true });

因为 Hammer 的 pan 手势默认是禁用的,特别是当它和其他手势(比如 swipe)共存时,容易被“抢走”识别权。你虽然调了 get('pan'),但没显式启用,有些浏览器就直接忽略了。

另外,CSS 里除了 touch-action: none;,还得确认这个元素是不是 inline 或者被包裹在有滚动容器里。如果 .item 是个 div 但里面内容很长、父容器有 overflow: auto;,那 Hammer 就可能被父级抢了触摸事件。

再补个保险的配置:

mc.get('pan').set({ direction: Hammer.DIRECTION_HORIZONTAL, enable: true });

如果还是没反应,你加个 tap 事件测试一下 Hammer 是否生效:

mc.on('tap', () => console.log('tap works'))

要是 tap 都不触发,那八成是 DOM 没选对或者被其他 JS 阻断了。要是 tap 正常、pan 不行,那就是手势识别优先级的问题——这时候你可能得加一句:

mc.get('swipe').set({ enable: false });

因为 swipe 默认和 pan 共存时会抢占识别权,尤其在 iOS 上。

插件可以,但 Hammer.js 这玩意儿真不讨喜,要是你项目里没别的手势依赖,不如直接用原生 touchstart touchmove touchend 写个轻量版,控制更稳,也不带那些隐式坑。
点赞
2026-02-25 17:58