防抖節(jié)流函數(shù):
防抖:
當持續(xù)觸發(fā)事件時, 一定時間內(nèi)沒有再觸發(fā)胡桃,事件處理函數(shù)執(zhí)行一次旁蔼,如果設(shè)定的時間到來之前梳凛,又一次觸發(fā)了事件耿币,就重新開始延時
假如期限值是200ms
1、在200ms 內(nèi)沒有再次觸發(fā)事件韧拒,那么就執(zhí)行函數(shù)淹接;
2、如果在200ms 內(nèi)再次觸發(fā)了滾動事件叛溢,那么當前計時器取消塑悼,重新開始計時;
image.png
function debounce(fn,delay){
let timer = null;
return function(){
if(timer){
//進入該分支語句楷掉,說明當前正在一個計時過程中厢蒜,并且又觸發(fā)了相同事件。所以要取消當前的計時烹植,重新開始計時
clearTimeout(timer)
}
timer = setTimeout(fn,delay)
}
}
//防抖debounce代碼:
function debounce(fn,delay) {
var timeout = null; // 創(chuàng)建一個標記用來存放定時器的返回值
return function (e) {
// 每當用戶輸入的時候把前一個 setTimeout clear 掉
if(timeout){
clearTimeout(timeout);
}
// 然后又創(chuàng)建一個新的 setTimeout, 這樣就能保證interval 間隔內(nèi)如果時間持續(xù)觸發(fā)斑鸦,就不會執(zhí)行 fn 函數(shù)
timeout = setTimeout(() => {
fn.apply(this, arguments);
}, delay);
};
}
// 處理函數(shù)
function handle() {
console.log('防抖:', Math.random());
}
//滾動事件
window.addEventListener('scroll', debounce(handle,500));
節(jié)流函數(shù):
當持續(xù)觸發(fā)事件時,保證一定時間段內(nèi)只調(diào)用一次事件處理函數(shù)草雕。
函數(shù)防抖(debounce):
觸發(fā)高頻事件后n秒內(nèi)函數(shù)只會執(zhí)行一次巷屿,如果n秒內(nèi)高頻事件再次被觸發(fā),則重新計算時間墩虹。
函數(shù)節(jié)流(throttle):高頻事件觸發(fā)嘱巾,但在n秒內(nèi)只會執(zhí)行一次憨琳,所以節(jié)流會稀釋函數(shù)的執(zhí)行頻率。
實現(xiàn)函數(shù)節(jié)流我們主要有兩種方法:時間戳和定時器
// 節(jié)流 (時間戳)
var throttle = function(fn,delay){
var pre = Date.now();
return function(){
var _this = this;
var args = arguments;
var now = Date.now();
if(now-pre>=delay){
fn.apply(_this,args);
pre = Date.now()
}
}
}
function handle() {
console.log(Math.random());
}
window.addEventListener('scroll', throttle(handle, 1000));
當觸發(fā)事件的時候旬昭,我們設(shè)置一個定時器篙螟,再次觸發(fā)事件的時候,如果定時器存在问拘,就不執(zhí)行闲擦,直到delay時間后,定時器執(zhí)行執(zhí)行函數(shù)场梆,并且清空定時器墅冷,這樣就可以設(shè)置下個定時器。
// 定時器
var throttle = function (fn,delay){
var timer = null;
return function (){
var _this = this;
var args= arguments;
if(!timer){
timer = setTimeout(()=>{
fn.apply(_this,args)
timer = null
},delay)
}
}
}
當remaining<=0時表示該執(zhí)行事件處理函數(shù)了(保證了第一次觸發(fā)事件就能立即執(zhí)行事件處理函數(shù)和每隔delay時間執(zhí)行一次事件處理函數(shù))或油。
如果還沒到時間的話就設(shè)定在remaining時間后再觸發(fā) (保證了最后一次觸發(fā)事件后還能再執(zhí)行一次事件處理函數(shù))寞忿。
當然在remaining這段時間中如果又一次觸發(fā)事件,那么會取消當前的計時器顶岸,并重新計算一個remaining來判斷當前狀態(tài)腔彰。
// 節(jié)流throttle代碼(時間戳+定時器):
var throttle = function (fn,delay){
var timer = null;
var startTime = Date.now(); // 進來開始的時間
return function(){
var currentTime = Date.now();
var remaining = delay-(currentTime-startTime);
var _this = this;
var args = arguments;
clearTimeout(timer);
if(remaining<=0){
fn.apply(_this.args)
startTime = Date.now()
}else{
timer = setTimeout(fn,remaining)
}
}
}