防抖和節(jié)流原理+實(shí)現(xiàn)
防抖(Debounce)和節(jié)流(Throttle)都是用于控制函數(shù)執(zhí)行頻率的機(jī)制,它們在處理高頻觸發(fā)的事件時非常有用。
1、防抖(Debounce)
防抖的原理是在事件被觸發(fā)后,等待一段時間(例如200毫秒)來執(zhí)行函數(shù),如果在等待時間內(nèi)事件被再次觸發(fā),則重新計時。這樣可以避免在短時間內(nèi)多次觸發(fā)事件導(dǎo)致函數(shù)頻繁執(zhí)行的問題,常用于輸入框搜索、窗口調(diào)整等場景。
function debounce(func, delay) {
let timer;
return function() {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, arguments);
}, delay);
}
}
// 使用 debounce 包裝需要防抖的函數(shù)
const debouncedFunc = debounce(function() {
console.log('防抖函數(shù)執(zhí)行');
}, 200);
// 在事件處理中使用 debouncedFunc
element.addEventListener('input', debouncedFunc);
Vue3自定義ref實(shí)現(xiàn)防抖
customRef
是 Vue 3 中的一個函數(shù),用于創(chuàng)建一個自定義的響應(yīng)式引用(Custom Ref)。它可以用來定義具有自定義行為的響應(yīng)式數(shù)據(jù),比如在數(shù)據(jù)發(fā)生變化時觸發(fā)特定的副作用。使用
customRef
函數(shù)需要傳入一個 factory 函數(shù),該函數(shù)會返回一個對象,該對象必須包含以下兩個屬性:
get
:一個無參數(shù)的函數(shù),用于獲取引用的當(dāng)前值。set
:一個帶有一個參數(shù)的函數(shù),用于設(shè)置引用的值。通過
customRef
創(chuàng)建一個自定義的響應(yīng)式引用。它內(nèi)部維護(hù)了一個變量value
存儲當(dāng)前值,并且在get
和set
方法中分別調(diào)用了track
和trigger
函數(shù),以便在引用的值發(fā)生變化時通知依賴追蹤和觸發(fā)更新。
/src/hooks/debounceRef.js
import { customRef } from 'vue';
export function debounceRef(value, duration = 1000) {
let timer = null;
return customRef((track, trigger) => {
return {
get() {
// 收集依賴
track();
return value;
},
set(newValue) {
clearTimeout(timer);
timer = setTimeout(() => {
value = newValue;
// 派發(fā)更新
trigger();
}, duration);
}
}
})
}
/src/App.vue
<template>
<div class="container">
<input type="text" v-model="text">
<p>{{ text }}</p>
</div>
</template>
<script setup>
import { debounceRef } from './hooks/debounceRef'
const text = debounceRef('', 500)
</script>
<style lang="less" scoped>
.container {
width: 80%;
margin: 0 auto;
}
</style>
2、節(jié)流(Throttle)
節(jié)流的原理是規(guī)定一個時間間隔(例如200毫秒),在該時間間隔內(nèi)只能觸發(fā)一次函數(shù)執(zhí)行。如果在該時間間隔內(nèi)多次觸發(fā)事件,只有第一次觸發(fā)會執(zhí)行函數(shù),后續(xù)的觸發(fā)會被忽略。節(jié)流常用于滾動事件、按鈕點(diǎn)擊等場景。文章來源:http://www.zghlxwxcb.cn/news/detail-853240.html
function throttle(func, interval) {
let lastTime = 0;
return function() {
let now = Date.now();
if (now - lastTime >= interval) {
func.apply(this, arguments);
lastTime = now;
}
}
}
// 使用 throttle 包裝需要節(jié)流的函數(shù)
const throttledFunc = throttle(function() {
console.log('節(jié)流函數(shù)執(zhí)行');
}, 200);
// 在事件處理中使用 throttledFunc
element.addEventListener('scroll', throttledFunc);
3、使用場景:
- 輸入框?qū)崟r搜索:在用戶輸入內(nèi)容時,通過防抖來減少請求的頻率,在用戶停止輸入一段時間后再發(fā)送請求。
- 窗口調(diào)整事件:當(dāng)窗口大小調(diào)整時,使用節(jié)流來控制回調(diào)函數(shù)的執(zhí)行頻率,避免過度頻繁地執(zhí)行。
- 頁面滾動事件:在監(jiān)聽頁面滾動時,使用節(jié)流來減少函數(shù)的觸發(fā)頻率,提高性能。
- 鼠標(biāo)移動事件:當(dāng)鼠標(biāo)在元素上移動時,使用節(jié)流來限制觸發(fā)函數(shù)的次數(shù),避免過于頻繁的回調(diào)。
總體來說,防抖和節(jié)流都是優(yōu)化高頻觸發(fā)事件的機(jī)制,可以提升性能和用戶體驗。根據(jù)具體需求選擇合適的方式來應(yīng)用。文章來源地址http://www.zghlxwxcb.cn/news/detail-853240.html
到了這里,關(guān)于【前端】防抖和節(jié)流原理+實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!