一直覺得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方法,它的定期檢查機制顯得太浪費了。