一直觉得setInterval给onscroll减压这个办法,定期去判断浏览器是否触发了滚动事件还是很挫的,近来在一个项目中突发奇想,让我找到了更好的方法。就是onscroll的时候,判断一下当前时间,详细看代码
var prevTime = + new Date;
window.onscroll = function() {
var now = + new Date;
//当前时间超过开始时间 200毫秒 则执行
if ( now - prevTime > 200 ) {
prevTime = now;
scrollHandle();
}
}
那我知道的方法有3个了
setTimeout
var timeout;
window.onscroll = function() {
clearTimeout( timeout );
timeout = setTimeout(function() {
scrollHandle();
}, 200);
}
setInterval
var changed = false;
window.onscroll = function() {
changed = true;
}
setInterval( function() {
if ( changed === true ) {
scrollHandle();
changed = false;
}
} , 200);
time
var prevTime = + new Date;
window.onscroll = function() {
var now = + new Date;
//当前时间超过开始时间 200毫秒 则执行
if ( now - prevTime > 200 ) {
prevTime = now;
scrollHandle();
}
}
现在好好总结一下,也好好测试一下它们的效率。
我的想法是用chrome中的timeline,检测每个方法在一个5秒滚动事件中的性能损耗,由于人工操作不能保障滚动时长,所以写一个点击事件去启动一个setInterval不断改变滚动条。
测试代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<button id="btn">test</button>
<div style="height:20000px;"></div>
<script>
var _window = window,
_document = document,
dElem = _document.documentElement,
body = _document.body,
interval,
i = 0;
function getScrollTop() {
return _window.pageYOffset
||
dElem.scrollTop
||
body.scrollTop
;
}
function test() {
var now;
if ( !interval ) {
now = + new Date;
interval = setInterval(function() {
//5秒后停止
if ( new Date - now > 5000 ) {
clearInterval( interval );
interval = null;
} else {
_window.scroll( 0, getScrollTop() + 5 );
}
}, 20);
}
}
function scrollHandle() {
console.log( ++i );
}
_document.getElementById( 'btn' ).onclick = function() {
test();
}
//setTimeout start
/*
var timeout;
_window.onscroll = function() {
clearTimeout( timeout );
timeout = setTimeout(function() {
scrollHandle();
}, 200);
}*/
//setTimeout end
//setInterval start
/*
var changed = false;
_window.onscroll = function() {
changed = true;
}
setInterval( function() {
if ( changed === true ) {
scrollHandle();
changed = false;
}
} , 200);
*/
//setInterval end
//time start
var prevTime = + new Date;
_window.onscroll = function() {
var now = + new Date;
//当前时间超过开始时间 200毫秒 则执行
if ( now - prevTime > 200 ) {
prevTime = now;
scrollHandle();
}
}
//time end
</script>
</body>
</html>
测试方法:
1. 打开chrome调试工具
2. 切换到timeline频道
3. timeline频道,点击“record”按钮
4. 页面中点击“test”按钮,触发滚动条动画
5. 动画停止后,timeline频道,再次点击“record”按钮,停止记录
6. 查看记录数据
测试结果:
setTimeout
setInterval
time
汇总
总结
setTimeout 是最慢的,原因也很简单,频繁setTimeout及clearTimeout,也由于这个原因,得等到滚动事件停止才能执行回调。setInterval性能不错,但对比time方法,它的定期检查机制显得太浪费了。