现代浏览器基本上都具有 线程化滚动功能(a threaded scrolling feature ),即使在运行计算量昂贵的 JavaScript 时,滚动也可以顺畅地运行。但此优化可能由于需要等待 touchstart
,touchmove
或 touchend
等事件处理程序的结果而失效。这可能原因是在 touch 事件处理函数中调用 preventDefault()
来完全阻止滚动。
addEventListener(
document,
'touchstart',
function (e) {
e.preventDefault(); // 完全阻止滚动
},
false
);
而浏览器这种阻止滚动行为其实是很少发生的,据统计表明:
针对上述问题,网上提供了如下的优化方案:
-
在 document 注册一个空的 touch 事件处理程序
const touchHandler = function () {}; document.addEventListener('touchmove', touchHandler); document.addEventListener('touchcancel', touchHandler); document.addEventListener('touchend', touchHandler);
-
通过 CSS 样式
touch-action
.classname { touch-action: none; }
然而这种问题不仅仅发生在 touch 事件上,wheel 事件也存在相同的问题。为了解决这个问题,WHATWG 引入了 Passive Event Listeners。
Passive Event Listeners 是 DOM Spec 的新特性。Chrome 51,Firefox 49 和 landed in WebKit 也开始实现了 Passive Event Listeners 特性。它允许开发人员明确 Touch Event 或 Wheel Event 是否需要阻止滚动,来优化滚动性能。
addEventListener(
document,
'touchstart',
function (e) {
e.preventDefault(); // 无效
},
{ passive: true } // 明确告诉浏览器不会调用 preventDefault() 来阻止滚动
);
上述实例,调用了 e.preventDefault();
,可能 console 面板打印如下提示信息:
如果在 touch
或 wheel
事件处理函数中调用 preventDefault()
,同时没有开启 { passive: true }
。此时可能 console 面板打印如下提示信息:
对比优化效果视频
如何检测 passive
// Test via a getter in the options object to see if the passive property is accessed
var supportsPassive = false;
try {
var opts = Object.defineProperty({}, 'passive', {
get: function () {
supportsPassive = true;
},
});
window.addEventListener('testPassive', null, opts);
window.removeEventListener('testPassive', null, opts);
} catch (e) {}
// Use our detect's results. passive applied if supported, capture will be false either way.
elem.addEventListener('touchstart', fn, supportsPassive ? { passive: true } : false);
参考文章
- Passive event listeners
- Passive event listeners explainer
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!