必须显式设置 { passive: false } 才能调用 event.preventdefault(),需在 addeventlistener 第三个参数中声明,配合 event.cancelable 判断及同步执行,ios 旧版本需降级处理。

当浏览器将 touchmove 或 scroll 类事件默认设为 passive: true 时,直接调用 event.preventDefault() 会报错:"Unable to preventDefault inside passive event listener"。这不是代码写错了,而是浏览器主动限制——为保障滚动流畅性,它提前声明“这个事件不允许取消默认行为”。要解决冲突,关键在于**提前声明监听器允许阻止默认行为**,而非事后补救。
必须显式设置 { passive: false }
在调用 addEventListener 时,第三个参数 options 中必须明确传入 { passive: false },且该选项需与事件类型匹配:
- 对
touchstart、touchmove、wheel等可能影响滚动的事件,若需阻止默认滚动(如自定义滑动、拖拽),必须加此配置 - 错误写法:
el.addEventListener('touchmove', handler)(浏览器按默认 passive 处理) - 正确写法:
el.addEventListener('touchmove', handler, { passive: false })
注意 iOS Safari 兼容性
iOS 12 之前版本不支持 passive: false,强行设置会被忽略,导致 preventDefault() 仍无效:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 稳妥做法:用特性检测判断是否支持 passive 选项
- 降级方案:对旧版 iOS 改用
pointerdown/pointermove事件(兼容性更好,且默认可 cancel) - 避免全局禁用 passive——只对真正需要干预滚动的元素启用,否则会牺牲页面滑动性能
检查 event.cancelable 再调用
不是所有事件都允许被取消,默认行为是否可阻止,应以 event.cancelable 值为准:
- 调用
preventDefault()前加判断:if (event.cancelable) event.preventDefault(); - 例如
scroll事件本身不可取消,即使设了passive: false,preventDefault()也无效 - 而
touchmove在passive: false下通常为true,此时调用才安全有效
避免异步调用 preventDefault
preventDefault() 必须在事件处理函数同步执行,延迟调用(如包裹在 setTimeout 或 Promise 回调中)完全失效:
- 错误:
setTimeout(() => e.preventDefault(), 0) - 正确:
e.preventDefault()直接写在事件回调第一行 - 尤其在 React 合成事件中,还需先调用
e.persist()防止对象被池化回收
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










