在日常工作當(dāng)中總會遇到一些時間連續(xù)觸發(fā)(比如搜索查詢,用戶輸入搜索過程中不斷調(diào)用后端api查詢數(shù)據(jù)、widow觸發(fā)resize或滾動時間等),這個時候為了不浪費(fèi)資源、優(yōu)化性能我們常常采用防抖/節(jié)流的方法來處理
防抖定義:函數(shù)執(zhí)行過一次后,在等待某時間段內(nèi)不能再次執(zhí)行,在等待時間內(nèi)觸發(fā)此函數(shù),則重新計算等待時間。
節(jié)流定義:規(guī)定一個單位時間,在這個單位時間內(nèi),只能有一次觸發(fā)事件的回調(diào)函數(shù)執(zhí)行,如果在同一個單位時間內(nèi)某事件被觸發(fā)多次,只有一次能生效。
在平時的工作中一定都有遇到過這種情況,點(diǎn)擊了一次按鈕之后事件還沒有處理完按鈕又被點(diǎn)擊了,正常情況下肯定是要避免這種情況的,這時候在代碼中我會這樣寫(使用定時器代替接口)。
<button onclick="submit(event,1000)">點(diǎn)擊</button> <script> // function submit(e) {
// setTimeout(() => {
// console.log(1);
// }, 1000)
// }
function submit(e, delay) {
e.target.disabled = true;
setTimeout(() => {
console.log(1);
e.target.disabled = false;
}, delay)
}
</script> 除了點(diǎn)擊事件,滾動事件也是非常要注意的,每次滾動條滾動到底部的時候都會去請求數(shù)據(jù),為了避免來回滾動造成連續(xù)發(fā)送多次請求的情況,上面的方法肯定是不適用的,看代碼
<script>
function debounce(fn, delay) {
var timer = null;
return function () {
if (timer !== null) {
clearTimeout(timer);
}
timer = setTimeout(fn, delay);
}
}
function handle() {
console.log('A');
}
window.addEventListener("scroll", debounce(handle, 1000));
</script>
在操作停止1秒鐘后才會去請求接口。
補(bǔ)充:
點(diǎn)擊事件的這種寫法非常有局限性,因為只能在button標(biāo)簽或者input標(biāo)簽中才能使用,如果事件并不是綁定在button標(biāo)簽或者input標(biāo)簽上的怎么辦?(不建議這么做,按鈕盡量使用button標(biāo)簽)
<div onclick="inner()">點(diǎn)擊</div> <script>
function throttle(fn, delay) {
let valid = true;
return function () {
if (!valid) {
return false;
}
fn();
valid = false;
setTimeout(() => {
valid = true;
}, delay)
}
}
function show() {
console.log(1);
}
var inner = throttle(show, 1500);
</script>
|
|