总结:要使 e.preventDefault();有效,那么显示的设置{passive:false}才会有效
有时候会在控制台看到
Unable to preventDefault inside passive event listener invocation
在passive:true,并且事件本身阻止了默认事件时,就会有上述错误
window.addEventListener("touchmove", handler, { passive: true });
function handler(e) {
//阻止默认事件,如点击<a>标签阻止其默认跳转事件
e.preventDefault();
//其他逻辑...
}
本质:
谷歌浏览器对event.preventDefault()(默认事件阻止)的检测机制变化导致的(听不懂?直接看下面)。
老版本:当用户触发我们定义的监听事件时候(如条件1中的“touchmove”事件),浏览器会主动检测对应的handler代码中是否有event.preventDefault(),以便进行默认事件阻止。但是这样做会增加响应时间,用户体验受到影响;
window.addEventListener("touchmove", handler);
window.addEventListener("touchmove", handler, { passive: true });
新版本的chrome默认就是passive:true
就是让chrome消极的去阻止默认事件,等价于不检测是否阻止默认事件,以达到提升浏览器性能的目的.但在这种情况下如果写了e.preventDefault(),相当于"违约,chrome就会在控制台报错
上面两个代码效果相同,我们经常用第一条,不知不觉中定义了一个被动监听事件。
那么问题就来了,我们不知道我们的事件已经默认被定义为了被动事件监听。结果我们在这个事件监听中调用了event.preventDefault(),浏览器就不高兴了,报错,告诉你:
“你定义的事件不是一个被动事件监听吗?不就是告诉我为了提高响应速度不要处理event.preventDefault()吗?为啥你还要调用event.preventDefault()!”
看了我们已经找到问题所在了。
总结:被动事件监听不能调用event.preventDefault()。
解决办法:
1、声明事件监听的时候设置为主动事件监听:
window.addEventListener(‘touchmove’, handler, { passive: false});
2、设置监听事件绑定的dom的CSS为:
touch-action:none
表示当触控事件发生在绑定的dom上时,不进行任何操作。