目录
一、场景
- vue项目中使用ElementUI的表单form校验单的时候,出现以下警告:
- [Violation] Added non-passive event listener to a scroll-blocking 'touchmove' event. Consider marking event handler as 'passive' to make the page more responsive.
- 虽然他不会直接影响项目出现报错或者无法正常运行,但是这系列警告的存在就会为以后项目运行出现未知问题埋下隐患。
二、问题解析
passive
是用于控制浏览器是否可以在滚动时取消事件的默认行为。当 passive
设置为 true
时,表示事件处理函数不会调用 preventDefault()
来阻止默认的滚动行为。
在一些滚动事件处理中,如果事件处理函数中调用了 preventDefault()
,浏览器会等待该函数执行完毕后再进行滚动,这可能导致滚动的延迟。通过将 passive
设置为 true
,可以告诉浏览器事件处理函数不会调用 preventDefault()
,从而使滚动更加流畅。
三、解决方案
新建ployfill.js
文件
这段代码是一个自执行的函数,其主要目的是修改浏览器中的事件监听器(Event Listener)行为。让我来解释一下:
-
首先,它使用了一个自执行函数
(function () { ... })()
的形式,这意味着这段代码会在加载时立即执行,而不需要显式调用。 -
在代码的第二行,它检查了
EventTarget
是否被定义,这是因为EventTarget
是用于处理事件的基本对象,通常在现代浏览器中是定义的。 -
如果
EventTarget
被定义,代码继续执行。它首先保存了原始的事件监听器方法EventTarget.prototype.addEventListener
到变量func
中。 -
然后,它重写了
EventTarget.prototype.addEventListener
方法。在新的方法中,它接受三个参数:type
(事件类型)、fn
(事件处理函数)和capture
(捕获阶段)。但这个新方法也保留了原始方法,将其保存在this.func
中。 -
接下来,代码检查
capture
是否是一个布尔值,如果不是布尔值,它会将capture
转化为一个对象。然后,它设置这个对象的passive
属性为false
,passive
是用于指示是否可以取消事件的属性。 -
最后,代码调用了原始的事件监听器方法,传递了相同的参数,包括修改后的
capture
参数。这就是为什么它保留了原始方法的原因,以确保事件监听器的行为不受太大影响。
总之,这段代码的主要目的是在事件监听器中添加一个默认的 capture
参数,以确保 passive
默认为 false
,同时保留了原始的事件监听器方法,以不影响现有的代码逻辑。这通常用于优化滚动等事件的性能。
//去除谷歌浏览器的scroll、wheel等事件警告
(function () {
if (typeof EventTarget !== "undefined") {
let func = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function (type, fn, capture) {
this.func = func;
if (typeof capture !== "boolean") {
capture = capture || {};
capture.passive = false;
}
this.func(type, fn, capture);
};
}
}());
在main.js
引入该文件(因为ployfill.js
中的解决思路是调整事件对象addEventListener
的原型,所以一定要在项目初始化之前,最好在项目最开头引入ployfill.js
)
import "@/common/polyfill" // 注意文件路径
四、解决方案二
default-passive-events是一个库,用于解决在移动设备上的滚动事件中的性能问题。在移动设备上,浏览器默认会将滚动事件处理为主动事件(active event),这意味着浏览器会等待滚动事件处理完毕后再进行页面渲染,从而导致页面的滚动不流畅。
default-passive-events库通过修改事件监听器的默认行为,将滚动事件处理为被动事件(passive event),从而解决了这个性能问题。被动事件不会阻塞页面渲染,因此可以提高滚动的流畅性。
具体而言,default-passive-events库会在事件监听器中添加一个passive选项,将事件处理为被动事件。这样一来,浏览器就知道该事件监听器不会调用preventDefault()方法来阻止默认行为,从而可以在不等待事件处理完毕的情况下进行页面渲染,提高了滚动的性能和流畅度。
总结起来,default-passive-events库通过将滚动事件处理为被动事件,解决了移动设备上滚动事件导致的性能问题,提高了页面的滚动流畅性。
yarn add default-passive-events
main.js引入
import 'default-passive-events'