-
防抖
轉載
讓某個函數在一定 事件間隔條件(去抖debounce) 或 時間間隔條件(節流throttle) 下才會去執行,避免快速多次執行函數(操作DOM,加載資源等等)給內存帶來大量的消耗從而一定程度上降低性能問題。
debounce: 當調用動作n毫秒后,才會執行該動作,若在這n毫秒內又調用此動作則將重新計算執行時間。
debounce使用場景:
- scroll事件(資源的加載)
- mouseover事件(拖拽)
- resize事件(響應式布局)
- keyup事件(輸入框文字停止打字后再進行校驗)
方法實現:
/**
* 防反跳。fn函數在最后一次調用時刻的delay毫秒之后執行!
* @param fn 執行函數
* @param delay 時間間隔
* @param isImmediate 為true,debounce會在delay時間間隔的開始時立即調用這個函數
* @returns {Function}
*/
function debounce(fn, delay, isImmediate) {
var timer = null; //初始化timer,作為計時清除依據
return function() {
var context = this; //獲取函數所在作用域this
var args = arguments; //取得傳入參數
clearTimeout(timer);
if(isImmediate && timer === null) {
//時間間隔外立即執行
fn.apply(context,args);
timer = 0;
return;
}
timer = setTimeout(function() {
fn.apply(context,args);
timer = null;
}, delay);
}
}
/* 方法執行e.g. */
var btn = document.getElementById('btn');
var el = document.getElementById('display');
var init = 0;
btn.addEventListener('click', debounce(function() {
init++;
el.innerText = init;
}, 1000,true));
- 截流
throttle:預先設定一個執行周期,當調用動作的時刻大于等于執行周期則執行該動作,然后進入下一個新周期。
throttle使用場景:
- click事件(不停快速點擊按鈕,減少觸發頻次)
- scroll事件(返回頂部按鈕出現隱藏事件觸發)
- keyup事件(輸入框文字與顯示欄內容復制同步)
- 減少ajax請求,降低請求頻率
方法實現:
/**
* 創建并返回一個像節流閥一樣的函數,當重復調用函數的時候,最多每隔delay毫秒調用一次該函數
* @param fn 執行函數
* @param delay 時間間隔
* @returns {Function}
*/
function throttle(fn, delay) {
var timer = null;
var timeStamp = new Date();
return function() {
var context = this; //獲取函數所在作用域this
var args = arguments; //取得傳入參數
if(new Date()-timeStamp>delay){
timeStamp = new Date();
timer = setTimeout(function(){
fn.apply(context,args);
},delay);
}
}
}
/* 方法執行 */
var btn = document.getElementById('btn');
var el = document.getElementById('display');
var init = 0;
btn.addEventListener('click', throttle(function() {
init++;
el.innerText = init;
}, 1000));
或者:
function throttle(fn, threshhold, scope) {
threshhold || (threshhold = 250);
var last,
deferTimer;
return function () {
var context = scope || this;
var now = +new Date(),
args = arguments;
if (last && now < last + threshhold) {
// hold on to it
clearTimeout(deferTimer);
deferTimer = setTimeout(function () {
last = now;
fn.apply(context, args);
}, threshhold);
} else {
last = now;
fn.apply(context, args);
}
};
}
浙公網安備 33010602011771號