passive event listener

今天在编写移动端app的时候,一个报错引起了我的注意,报错如下:

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

因为自己以前也没有见过这个错误,所以百度了下,这个特性是从Chrome 51 开始的,旨在提升页面的流畅度,具体的解释如下(摘自SegmentFault):

当你触摸滑动页面时,页面应该跟随手指一起滚动。如果你绑定了一个触摸事件(大概执行 200 毫秒),浏览器就犯迷糊了:如果你在事件绑定函数中调用了 preventDefault,那么页面就不应该滚动;但是浏览器一开始不知道你有没有调用,只能先执行你的函数,等 200 毫秒后,浏览器才知道,“哦,原来你没有阻止默认行为,好的我马上滚”。此时,页面开始滚。

经统计,80% 左右的触摸事件都没有被 preventDefault 阻止,这些等待的时间都被浪费掉了。使用 Passive Event Listeners,开发者能够提前告诉浏览器:“我不调用 preventDefault 函数来阻止事件默认行为”,那么浏览器就无需等待事件执行完成,而是直接执行默认行为(滚动)。

在这里我们就有必要来了解一下addEventListener方法,该方法接收三个参数,window.addEventListener(type, fn, { passive: false }),type表示监听事件类型的字符串,fn作为事件调用的函数,第三个参数默认为false,表示浏览器检测使用的preventDefault。

从passive event listener 被引进Chrome开始,我们就可以通过给addEventListener 设置第三个参数{passive:true}来避免浏览器对prevent Default 的检测,从而使滑动显得比较流畅,当我们给addEventListener 设置了{passive: true}时,这个监听器也就被称为passive event listener。

解决方案:
理解了出现这个问题的原理,我们就来说说解决问题的方案:
1、设置全局css样式

*{
	//当触控事件发生在元素上时,不进行任何操作
	touch-action: none;
 }

2、使用JS的时间监听方法来解决

window.addEventListener('type',fn,{passive: true});

总结:
其实这个问题不会造成页面的崩溃,但是它的的确确的影响了性能的优化,所以来记录下自己的解决方法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章