Hammer.js 手势识别在某些元素上不生效是怎么回事?
我用 Hammer.js 给一个 div 加了 pinch 和 pan 手势,但在真机上测试时发现有时候手势完全没反应,尤其是当这个 div 有 overflow: hidden 的时候。我试过加 touch-action: none 也没用,是不是和 CSS 有冲突?
这是我的样式代码:
.gesture-area {
width: 100%;
height: 300px;
background: #f0f0f0;
overflow: hidden;
touch-action: none;
-webkit-user-select: none;
user-select: none;
}
JS 里就是 new Hammer(element) 然后 on(‘pinch pan’),逻辑很简单,但就是偶尔失效,特别在 iOS 上。有人遇到过类似问题吗?
另外建议把Hammer初始化写成这样更稳:
iOS的overflow:hidden会吃掉touch事件,这坑我踩过三次才记住。
先说解决方案,分三步走:
1. CSS部分需要额外加几个属性:
2. JS初始化Hammer时要配置识别器参数:
3. 在容器元素上添加事件监听:
原理是这样的:iOS的WebKit对overflow: hidden的元素有特殊处理,会延迟或取消部分触摸事件。translateZ(0)触发硬件加速,-webkit-overflow-scrolling: touch强制启用iOS原生滚动行为(虽然我们不需要滚动,但这个开关会影响事件传递)。
Hammer.js的坑在于,默认配置下它可能不会正确处理复合手势。需要显式声明Pan和Pinch的配置,特别是direction参数一定要设对。
测试的时候需要注意:
1. 在真机上测试,模拟器不靠谱
2. 先用最简单的手势测试,比如单指滑动
3. 确保没有其他JS库干扰触摸事件
我去年在移动端项目上被这个问题折磨了两天,最后发现是iOS的触摸事件冒泡机制和CSS属性共同导致的。现在看到这类问题都PTSD了...