vue源码知识点-passive参考EventTarget.addEventListener()移动端被动Web界面滚动性能优化的作用及原理:被动事件监听器源码拦截varsupportsPassive=false;如果(在浏览器中){尝试{varopts={};Object.defineProperty(opts,'passive',({get:functionget(){/*istanbulignorenext*/supportsPassive=true;}}));//https://github.com/facebook/flow/issues/285window.addEventListener('test-passive',null,opts);}catch(e){}}addEventListener在早期的MDN标准中,addEventListener的用法是这样的target.addEventListener(type,listener,useCapture);但是最新的标准变成了这样target.addEventListener(type,listener,options);也就是说,第三个参数从useCapture(Boolean)更改为options(object),但并非所有浏览器都已经支持新的标准被动用法target.addEventListener(type,listener,{capture:false,//capturepassive:false,once:false//只触发一次})passive:Boolean,当设置为true时,表示监听器永远不会调用preventDefault()。如果侦听器仍然调用此函数,客户端将忽略它并抛出控制台警告。passive的作用Passive主要用来优化浏览器页面滚动的性能,让页面滚动更流畅滚动是浏览器的默认行为,可以通过preventDefault来阻止,比如window.addEventListener("mousewheel",function(e){e.preventDefault()},{passive:false});添加上述代码后,页面将无法滚动,因为浏览器无法提前知道事件处理程序中是否会调用preventDefault(),需要等到事件处理程序执行完毕后,才会执行默认行为。但是事件处理器的执行比较耗时,会导致页面卡顿。我们可以通过将passive传为true来显式地告诉浏览器,事件处理程序不会调用preventDefault来阻止默认的滑动行为,浏览器不会等待事件处理函数执行完成后再执行滚动。即使在滚动事件中写了死循环,浏览器仍然可以正常处理页面的滑动。引用的vue源码,其实这段代码的作用就是polyfill,用来检测浏览器是否支持passive。正如在addEventListener部分介绍的,并非所有浏览器都支持设置passivevarsupportsPassive=false;if(inBrowser){try{varopts={};Object.defineProperty(opts,'passive',({get:functionget(){/*istanbulignorenext*/supportsPassive=true;}}));//https://github.com/facebook/flow/issues/285window.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
