說到防抖和節流相信大家都不陌生,這兩個東西大家可能多多少少都有用到過,最少也有聽。簡單來說,防抖和節流都是用來減少函數執行的頻率,以達到優化項目性能或者實現特定功能的效果。 ...
說到防抖和節流相信大家都不陌生,這兩個東西大家可能多多少少都有用到過,最少也有聽過
古人雲,溫故而知新。雖然可能已經很熟悉防抖和節流了,但不妨再看一看鞏固一下知識
什麼?你說你不僅不會手寫防抖和節流,也沒有聽過。那也沒事,下文會詳細介紹的
防抖和節流有什麼用?
簡單來說,防抖和節流都是用來減少函數執行的頻率,以達到優化項目性能或者實現特定功能的效果
防抖
定義:事件被觸發一定時間後再執行回調。如果在這段時間內又被觸發了,則重新開始計算時間
常用場景
- 輸入框遠程查詢事件
- 線上文檔自動保存
- 瀏覽器視口大小改變
例子
張三在某平臺搜索一本書籍,發現搜索建議並不是瞬間就出現的,而是自己輸入片語結束後出現的。那麼該平臺在此搜索框可能做了什麼操作?
代碼實現
<body>
<input type="text" id="searchElement" />
</body>
<script>
const searchElement = document.getElementById('searchElement');
const debounce = (fn, initial) => {
let timer = null;
return () => {
clearTimeout(timer);
timer = setTimeout(fn, initial);
};
};
searchElement.oninput = debounce(function (event) {
const value = searchElement.value;
if (value) console.log(value, '請求值');
}, 1000);
</script>
節流
定義:在單位時間內只觸發一次函數,若單位時間內多次觸發只有一次生效
常用場景
- 按鈕提交事件(當然也可做成點擊後就loading)
- 頁面滾動事件的觸發
- 累計計算滑鼠移動距離
例子
張三參加某平臺周年慶活動,他選購了某熱門飲品並一直點擊搶購按鈕,卻發現並不是每次點擊都會有響應的。那麼該平臺前端可能做了什麼限制?
代碼實現
<body>
<button type="submit" id="buttonElement">搶購</button>
</body>
<script>
function throttle(fn, interval) {
let timer;
return (event) => {
if (timer) return false;
timer = setTimeout(() => {
clearTimeout(timer);
timer = null;
fn(event);
}, interval);
};
}
var btnClick = document.getElementById('buttonElement');
btnClick.addEventListener('click', throttle(function (event) {
console.log(event, '點擊了')
}, 1000));
</script>
可以看到,張三瘋狂點擊搶購,但還是每秒只響應1次
節流(立即執行)
細心的同學可能發現了,上面這個代碼有個弊端,那就是在張三第一次點擊的時候也隔了1秒才響應,這不免也太坑了。正常來說第一次應該直接響應的,並且在連續點擊結束後的第一次也應該立即觸發,其實想實現這樣的效果也不難
<body>
<button type="submit" id="buttonElement">搶購</button>
</body>
<script>
function throttle2(fn, interval) {
let init = false; // 引入一個參數記錄狀態
let timer;
return (event) => {
if (init) return;
init = true;
clearTimeout(timer);
timer = setTimeout(() => {
init = false;
}, interval);
fn(event);
}
}
var btnClick = document.getElementById('buttonElement');
btnClick.addEventListener('click', throttle2(function (event) {
console.log(event, '點擊了')
}, 2000));
</script>
可以看到第一次點擊直接列印,第二次瘋狂點擊只列印一次,最後一次點擊也是直接列印
引入Lodash實現
GitHub地址:https://github.com/lodash/lodash
官方文檔:https://www.lodashjs.com/
防抖
import _ from 'lodash';
debounceHandle: _.debounce(function() {
console.log('業務代碼');
}, 2000, { // 在n毫秒內觸發
leading: true, // 第一次點擊立刻執行,預設為true
trailing: true // 節流結束後立刻執行,預設為true
});
節流
import _ from 'lodash';
throttleHandle: _.throttle(function() {
console.log("業務代碼");
}, 2000);