Unable to preventDefault inside passive event listener due to target being treated as passive

事件现象

1
2
3
document.addEventListener('touchstart', function (e) {
e.preventDefault();
});

chrome 控制台报错:

1
[Intervention] Unable to preventDefault inside passive event listener due to target being treated as passive. See https://www.chromestatus.com/features/5093566007214080

document 上监听 touch 类事件时,如果在 handler 里调用了 e.preventDefault(),则会报错:不能给passive(被动的)事件监听器 preventDefault,因为它被认为是 passive

相关知识

addEventListener() 的第三个参数(可选)为以下二选一:

  • useCaptureboolean,默认值false)为 true 表示 listener 会在该类型的事件捕获阶段传播到该 EventTarget 时触发
  • optionsobject
    • captureboolean,默认值 false,同 useCapture
    • once (boolean,默认值 false) 为 true 表示 listener 在添加之后最多只调用一次
    • passive (boolean,默认值 false ) 为 true 表示 listener 调用 preventDefault() 无效并报错

事件原因

Chrome 56 开始,如果我们给 document 绑定 touchmove 或者 touchstart 事件的监听器,这个 passive 是会被默认设置为true 以提高性能查阅

解决方法

  • 避免在 handler 里调用 e.preventDefault(),提高性能
  • addEventListener 里第三个参数设置为 {passive:false}
1
2
3
4
5
6
7
8
9
document.addEventListener(
'touchstart',
function (e) {
e.preventDefault();
},
{
passive: false,
}
);