多点触控时如何防止页面缩放但保留自定义手势?
我在做一个移动端的画板应用,想禁用浏览器默认的双指缩放,但又希望用自己的 JavaScript 逻辑处理 pinch 手势。试过在 meta 里加 user-scalable=no,但 iOS 上还是偶尔会触发缩放,而且影响了其他 touch 事件。
也试过给 canvas 加 touch-action: none,结果发现这样连单指拖动都失效了……是不是我 CSS 写得不对?下面是我目前的样式:
canvas {
touch-action: none;
-webkit-user-select: none;
user-select: none;
width: 100%;
height: 100%;
}
有没有办法只禁用缩放,但保留所有 touchstart/touchmove 事件的完整控制权?
CSS的话,给 canvas 设置 touch-action: pan-x pan-y 让单指拖动正常工作,同时阻止默认的缩放行为。完整 CSS 可以这样写:
然后在 JavaScript 中,监听 touchstart 和 touchmove 事件,通过 event.preventDefault() 来阻止浏览器默认行为。要注意的是,不能一开始就 preventDefault,而要在识别出手势意图后再调用。
这里有个简单的例子来处理 pinch 手势:
这样就能既保留完整的 touch 事件控制权,又防止了默认缩放行为。记得在 touchend 时清理状态变量 initialPinchDistance。这个方案在实际项目里挺稳的,应该能解决你的问题。
首先把 meta 标签里的 user-scalable=no 去掉,这个属性在现代浏览器里经常会导致其他问题。然后我们用更精细的 CSS 和 JavaScript 来控制手势。
试试这样写 CSS:
这样可以保留单指拖动,同时阻止默认缩放行为。接下来在 JavaScript 里拦截 touchstart 和 touchmove 事件,自己实现 pinch 手势逻辑:
注意这里把事件监听器的 passive 设为 false,这样才能正常调用 preventDefault()。这方案我在几个项目里都验证过,应该能满足你的需求。折腾这些手势真是个体力活啊。