事件监听选项的passive属性

关于touch事件监听选项的passive属性

描述

以前浏览器会先执行监听器函数,对于滑动事件来说,会存在一个问题:这个监听器里,有没有调用preventDefault()方法?
如果调了preventDefault(),那明显不应该进行滚动操作。
如果没调,那就最好先进行滑动,避免了先执行监听器造成的延迟卡顿。

所以,最新的DOM事件规范,对事件监听的第三个可选参数做了修改:由单个属性变为一个可选的对象。
原来:option,现在:option。变更后的对象属性:{passvie:boolean,useCapture:boolean}
passive:true,表示监听器明确不会调用preventDefault(),这个时候,浏览器会立即执行滑动的默认行为。应尽量使用true,尤其是移动端。
即使你调用了preventDefault()方法,也会被浏览器忽略:Unable to preventDefault inside passive event listener due to target being treated as passive.
passive:false,浏览器禁止滑动行为,等待监听器执行。如果执行时间大于100ms,浏览器就会建议你passive:true

polyfill

var supportsPassive = false; // 初始值
try {
var opts = Object.defineProperty({}, 'passive', {
get: function() {
supportsPassive = true;
}
});
window.addEventListener("test", null, opts);// 关键代码。如果浏览器尝试去读取passive属性,就是支持passive的
} catch (e) {}

// 用例
elem.addEventListener(
'touchstart',
fn,
supportsPassive ? { passive: true } : false // 如果支持就传一个选项对象,不支持还传原来的boolean
);