vue源码知识点-passive

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主要用于优化浏览器页面滚动的性能,让页面滚动更顺滑

  1. 滚动是浏览器的默认行为,它可以被preventDefault阻止,如

    window.addEventListener("mousewheel", function(e){
      e.preventDefault()
    }, {
      passive: false
    });

    添加上述代码后,页面将无法滚动

  2. 由于浏览器无法预先知道一个事件处理函数中会不会调用 preventDefault(),它需要等到事件处理函数执行完后,才能去执行默认行为,然而事件处理函数执行是要耗时的,这样一来就会导致页面卡顿
  3. 我们可以通过传递 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

你可能感兴趣的:(javascript,vue.js)