touchmove事件 与 被动事件(passive event) 问题
touchmove 事件 与 被动事件(passive event) 问题
[TOC]
产生原因:
- 条件 1:使用监听事件时候,第三个参数配置了 passive 为 true(说明指定了这个监听为一个被动监听)
1 |
|
- 条件 2:上条件中的被动监听的 handler 中调用了
1 |
|
上述两个条件同时成立的时候,就会报标题中错误或警告。
本质:
谷歌浏览器对 event.preventDefault()(默认事件阻止)的检测机制变化导致的(听不懂?直接看下面)。
老版本
:当用户触发我们定义的监听事件时候(如条件 1 中的“touchmove”事件),浏览器会主动检测对应的 handler 代码中是否有 event.preventDefault(),以便进行默认事件阻止。但是这样做会增加响应时间,用户体验受到影响;
新版本
:
默认不再检测 event.preventDefault(),直接响应用户操作。这相当于把我们定义的事件监听都设置成了被动事件监听。具体代码就是:
1 |
|
上面两个代码效果相同,我们经常用第一条,不知不觉中定义了一个被动监听事件。
那么问题就来了,我们不知道我们的事件已经默认被定义为了被动事件监听。结果我们在这个事件监听中调用了 event.preventDefault(),浏览器就不高兴了,导致报错,告诉你:
“你定义的事件不是一个被动事件监听吗?不就是告诉我为了提高响应速度不要处理 event.preventDefault()吗?为啥你还要调用 event.preventDefault()!”
看了我们已经找到问题所在了。
总结: 被动事件监听不能调用 event.preventDefault()。
值得说的是: Passive Event Listeners 特性当前仅支持 mousewheel/touch 相关事件。
解决办法:
1、声明事件监听的时候设置为主动事件监听:
1 |
|
2、设置监听事件绑定的 dom 的 CSS 为:
1 |
|
表示当触控事件发生在绑定的 dom 上时,不进行任何操作。
引申:
在解决下图出现的警告时,通常使用 default-passive-events 包。可以解决。
该问题主要是因为 chrome51 后 google 为了滚动等事件的性能,所有的事件都需要默认绑定 被动监听器了,但 element 中并没有绑定,所有会抛出警告。
_default-passive-events_ 包,可以通过修改事件的 passive 设置为 true, 解决这个警告。又因为element是在事件监听器的callback(handler)中使用`event.preventDefault()`清除默认事件的。所有就完全成全了上述的 `报错的产生原因`,导致上述的**报错**。所以在使用element组件时不建议再用 _default-passive-events_ 包。警告就警告吧。
ps:
关于 touch-action 还有很多设置,我也在学习中。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!