防抖(debounce)
對于短時間內(nèi)連續(xù)觸發(fā)的事件(上面的滾動事件)借帘,防抖的含義就是讓某個時間期限(如上面的1000毫秒)內(nèi)奕剃,事件處理函數(shù)只執(zhí)行一次。
在第一次觸發(fā)事件時在扰,不立即執(zhí)行函數(shù)霉晕,而是給出一個期限值比如200ms庭再,然后:
如果在200ms內(nèi)沒有再次觸發(fā)滾動事件,那么就執(zhí)行函數(shù)
如果在200ms內(nèi)再次觸發(fā)滾動事件牺堰,那么當前的計時取消拄轻,重新開始計時
效果:如果短時間內(nèi)大量觸發(fā)同一事件,只會執(zhí)行一次函數(shù)伟葫。
實現(xiàn):借助閉包和setTimeout這個函數(shù)恨搓,來實現(xiàn)(需要一個變量來保存計時,考慮維護全局純凈)
/*
* fn [function] 需要防抖的函數(shù)
* delay [number] 毫秒筏养,防抖期限值
*/
function debounce(fn,delay){
let timer = null //借助閉包
return function() {
if(timer){
clearTimeout(timer)
}
timer = setTimeout(fn,delay) // 簡化寫法
}
}
// 然后是舊代碼
function showTop () {
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log('滾動條位置:' + scrollTop);
}
window.onscroll = debounce(showTop,1000) // 為了方便觀察效果我們?nèi)€大點的間斷值斧抱,實際使用根據(jù)需要來配置
節(jié)流(throttle)
節(jié)流:如果短時間內(nèi)大量觸發(fā)同一事件,那么在函數(shù)執(zhí)行一次之后撼玄,該函數(shù)在指定的時間期限內(nèi)不再工作夺姑,直至過了這段時間才重新生效
借助setTimeout來做一個簡單的實現(xiàn)墩邀,加上一個狀態(tài)位valid來表示當前函數(shù)是否處于工作狀態(tài):
function throttle(fn,delay){
let valid = true
return function() {
if(!valid){
//休息時間 暫不接客
return false
}
// 工作時間掌猛,執(zhí)行函數(shù)并且在間隔期內(nèi)把狀態(tài)位設為無效
valid = false
setTimeout(() => {
fn()
valid = true;
}, delay)
}
}
/* 請注意,節(jié)流函數(shù)并不止上面這種實現(xiàn)方案,
例如可以完全不借助setTimeout,可以把狀態(tài)位換成時間戳荔茬,然后利用時間戳差值是否大于指定間隔時間來做判定废膘。
也可以直接將setTimeout的返回的標記當做判斷條件-判斷當前定時器是否存在,如果存在表示還在冷卻慕蔚,并且在執(zhí)行fn之后消除定時器表示激活丐黄,原理都一樣
*/
// 以下照舊
function showTop () {
var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
console.log('滾動條位置:' + scrollTop);
}
window.onscroll = throttle(showTop,1000)