Unable to preventDefault inside passive event listener due to target being treated as passive.
不止是iOS,chrome等浏览器均存在类似问题,原因在于其在实现时的一点小改动:
浏览器只有在执行事件处理函数后才能知道有没有触发preventDefault,故页面会有延迟。为了解决这种延迟,从而让页面滚动的效果如丝般顺滑,从 chrome56 开始,在 window、document 和 body 上注册的 touchstart 和 touchmove 事件处理函数,会默认为是 passive: true。浏览器忽略 preventDefault() 就可以第一时间滚动了。
但这样的后果是,如果在以上这 3 个元素的 touchstart 和 touchmove 事件处理函数中调用 e.preventDefault() ,会被浏览器忽略掉,并不会阻止默认行为。
解决办法一:css touch-action: none;
解决办法二:注册处理函数时,用如下方式,明确声明为不是被动的
window.addEventListener('touchmove', func, { passive: false })