背景
????今天在coding的時候,做了一個搜索框,也正是這個搜索框,讓我和后臺小伙伴直接由鐵磁變為塑料兄弟。那到底發生啥了呢?其實很簡單,其實很無奈,就是我用王者的手速把他的接口訪問崩了!
????我們在平時開發的時候,會有很多場景會頻繁觸發事件,比如說搜索框實時發請求,onmousemove,resize,onscroll等等,有些時候,我們并不能或者不想頻繁觸發事件,咋辦呢?這時候就應該用到函數防抖和函數節流了!
函數防抖(debounce)
????什么是防抖?短時間內多次觸發同一個事件,只執行最后一次,或者只在開始時執行,中間不執行。舉個栗子:你去乘坐公交車,不停地上人,連續上人的過程中司機師傅是不會開車的,只有當最后一個人上車了,老司機才會開車!嘿嘿嘿!我們以不停地觸發onmousemove事件,讓數字 1為例。代碼如下:
- 不使用防抖和節流,數字會像得了羊癲瘋一樣不停地增長
//變量初始化
var xcd = document.getElementById(
'xcd'),count = 1;
//要執行的操作 數字 1
function doSomething() {xcd.innerHTML = count ;
};
//觸發onmousemove事件 正常情況下
xcd.onmousemove =
doSomething;
//綠色基礎版:
function debounce(
doSomething,
wait){var timeout;//需要一個外部變量,為增強封裝,所以使用閉包
return function(){var _this = this,_arguments = arguments;//arguments中存著eclearTimeout(timeout);timeout =
setTimeout(
function(){
doSomething.apply(_this,_arguments); },
wait);}
}
//觸發onmousemove事件
xcd.onmousemove = debounce(
doSomething,1000);
????這個綠色基礎版雖然簡單,但是已經能夠解決大部分需求場景了,沒有啥特殊需求使用這個版本就行了!用起來簡直像吃了巴豆一樣,duangduangduang,極其通暢!But,還會有一些其他需求,比如我想立即執行,就是連續觸發事件的開始時立即執行一次,后連續觸發不執行,我們用isImmediate表示是否立即執行,代碼如下:
//立即執行版
function debounce(
doSomething,
wait,isImmediate){var timeout;
return function(){var _this = this,_arguments = arguments;clearTimeout(timeout);
if(isImmediate){var isTrigger = !timeout;timeout =
setTimeout(
function(){timeout = null;},
wait)isTrigger&&
doSomething.apply(_this,_arguments);}
else{timeout =
setTimeout(
function(){
doSomething.apply(_this,_arguments); },
wait);}}
}
//觸發onmousemove事件
xcd.onmousemove = debounce(
doSomething,1000,
true);
函數節流(throttle)
????什么是節流?節流是連續觸發事件的過程中以一定時間間隔執行函數。節流會稀釋你的執行頻率,比如每間隔1秒鐘,只會執行一次函數,無論這1秒鐘內觸發了多少次事件。
????舉個栗子:你每天要喝好多水,但是你不會每喝完一口水都要去一次廁所,如果有盆友是醬紫的話,我勸你還是去醫院看看吧→_→廁所看你都煩~你雖然一直在喝水,但是不會一直去廁所,通常的節奏是!喝水喝水喝水上廁所!喝水喝水喝水上廁所!雖然一直在觸發,但是每隔一段時間只會執行一次操作,這就是函數節流!
//綠色基礎版之時間戳版
function throttle(
doSomething,
wait){var _this,_arguments,initTime = 0;
return function(){var now = new Date();//將new date()轉化為時間戳_this = this;_arguments = arguments;
if(now - initTime>
wait){
doSomething.apply(_this,_arguments);initTime = now;}}
}
//觸發onmousemove事件
xcd.onmousemove = throttle(
doSomething,1000);
//綠色基礎版之定時器版
function throttle(
doSomething,
wait){var timeout;
return function(){var _this = this;_arguments = arguments;
if(!timeout){timeout =
setTimeout(
function(){timeout = null;
doSomething.apply(_this,_arguments);},
wait);};}
}
//觸發onmousemove事件
xcd.onmousemove = throttle(
doSomething,1000);
????同樣,以上兩個節流的綠色基礎版也可以滿足大多數需求場景啦!這兩個版本有什么區別呢?時間戳版會在開始時立即執行一次,最后時間間隔內不再執行;定時器版開始時不執行,最后時間間隔內再執行一次。可以根據自己的實際需求選擇合適的版本。
????當然,可能還有一些BT的產品會問你,能不能先立即執行一次,中間固定間隔時間執行,最后在執行一次呢?這就到了裝B的時候了。像我這么牛X的前端,必須的啊,把兩種合在一起就行了,雙修什么的最喜歡了*@ο@*
//節流之雙劍合璧版
function throttle(
doSomething,
wait) {var timeout, _this, _arguments,previous = 0;var later =
function() {previous = new Date();timeout = null;
doSomething.apply(_this, _arguments)};var throttled =
function() {var now = new Date();//下次觸發
doSomething 剩余的時間var remaining =
wait - (now - previous),_this = this;_arguments = arguments;// 如果沒有剩余的時間了
if (remaining <= 0) {
if (timeout) {clearTimeout(timeout);timeout = null;}previous = now;
doSomething.apply(_this, _arguments);}
else if (!timeout) {timeout =
setTimeout(later, remaining);}};
return throttled;
}
//觸發onmousemove事件
xcd.onmousemove = throttle(
doSomething,1000);
深入理解函數防抖和節流,合理選擇防抖或節流,能解決很多帕金森疾病,實乃出門旅行,居家生活之必備良品!OK就醬,我就是我,我瞅自己都上火!不定期分享一些前端知識點和面試點,喜歡點波關注唄!
參考:https://github.com/mqyqingfeng/Blog
總結
以上是生活随笔為你收集整理的虾扯蛋之函数防抖和节流的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。