vue源码知识点-passive
参考
源码截取
var supportsPassive = false;
if (inBrowser) {
try {
var opts = {};
Object.defineProperty(opts, 'passive', ({
get: function get () {
/* istanbul ignore next */
supportsPassive = true;
}
})); // https://github.com/facebook/flow/issues/285
window.addEventListener('test-passive', null, opts);
} catch (e) {}
}
addEventListener
早期的MDN标准中,addEventListener的用法是这样的
target.addEventListener(type, listener, useCapture);
但最新的标准已经变成这样
target.addEventListener(type, listener, options);
也就是说,第三个参数从useCapture(Boolean)变成了options(对象),但并不是所有浏览器都已支持新的标准
passive的用法
target.addEventListener(type, listener, {
capture: false, //捕获
passive: false,
once: false //只触发一次
})
passive: Boolean,设置为true时,表示 listener 永远不会调用 preventDefault()。如果 listener 仍然调用了这个函数,客户端将会忽略它并抛出一个控制台警告。
passive的作用
passive主要用于优化浏览器页面滚动的性能,让页面滚动更顺滑
-
滚动是浏览器的默认行为,它可以被preventDefault阻止,如
window.addEventListener("mousewheel", function(e){ e.preventDefault() }, { passive: false });
添加上述代码后,页面将无法滚动
- 由于浏览器无法预先知道一个事件处理函数中会不会调用 preventDefault(),它需要等到事件处理函数执行完后,才能去执行默认行为,然而事件处理函数执行是要耗时的,这样一来就会导致页面卡顿
- 我们可以通过传递 passive 为 true 来明确告诉浏览器,事件处理程序不会调用 preventDefault 来阻止默认滑动行为,浏览器就不会等待事件处理函数执行完成再执行滚动,即使滚动事件里面写一个死循环,浏览器也能够正常处理页面的滑动
文章开头引用的vue源码分析
再回过头来看文章开头引用的vue源码,实际上这段代码的功能是polyfill,用来检查浏览器是否支持passive,如同addEventListener部分所介绍的,并不是所有浏览器都已支持设置passive
var supportsPassive = false;
if (inBrowser) {
try {
var opts = {};
Object.defineProperty(opts, 'passive', ({
get: function get () {
/* istanbul ignore next */
supportsPassive = true;
}
})); // https://github.com/facebook/flow/issues/285
window.addEventListener('test-passive', null, opts);
} catch (e) {}
}
window.addEventListener('test-passive', null, opts);
这行代码设置了一个空事件处理器,目的不是要在之后触发'test-passive'事件,实际上,当执行这行代码时,addEventListener第三个参数opts是个对象,这样如果浏览器将第三个参数认定为对象并且支持设置passive的话,passive选项值会被检查,即浏览器会获取opts.passive的值,这样就会调用get函数,supportsPassive被设为true
如果浏览器不支持passive,那么就不会去获取opts.passive,supportsPassive自然保持为false
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。