一、js防抖函數怎麼寫
防抖函數的基本思路是在函數觸發時,設定一個計時器來延遲執行函數,若在延時期間函數被再次觸發,則重新計時,直到延時期滿。這個計時器可以使用setTimeout來實現。具體實現如下所示:
function debounce(func, wait, immediate) { let timeout; return function() { const context = this; const args = arguments; const callNow = immediate && !timeout; clearTimeout(timeout); timeout = setTimeout(function() { timeout = null; if (!immediate) { func.apply(context, args); } }, wait); if (callNow) { func.apply(context, args); } }; }
以上代碼中,debounce函數接收3個參數:需要延遲執行的函數、延遲的毫秒數以及一個布爾值,表示是否在函數被觸發時立即執行函數。返回一個新函數,在調用這個新函數時就會延遲執行傳入的函數。
二、js防抖函數和節流函數的區別
js中的防抖函數和節流函數都是為了解決函數頻繁觸發引起的性能問題,它們的區別在於:
- 函數節流:一段時間內只能執行一次
- 函數防抖:只有在上一次觸發函數後的一段時間內沒有再次觸發,才會執行函數
簡單說,函數節流的思路是:以一定時間間隔來執行函數,而函數防抖的思路是:在一定時間段內不允許函數執行,直到時間結束後再執行。
三、js防抖函數立即執行
在前面的js防抖函數中,我們實現的是延遲執行函數,如果要實現立即執行函數,可以根據傳入的第3個參數immediate。當immediate為true時,函數立即執行,當immediate為false或不傳時,函數延遲執行。
function debounce(func, wait, immediate) { let timeout; return function() { const context = this; const args = arguments; clearTimeout(timeout); if (immediate) { const callNow = !timeout; timeout = setTimeout(function() { timeout = null; }, wait); if (callNow) { func.apply(context, args); } } else { timeout = setTimeout(function() { func.apply(context, args); }, wait); } } }
四、js按鈕防抖函數
在前端頁面中,按鈕可能會被用戶頻繁的點擊,導致後端接口被頻繁地調用,可能會造成系統崩潰。為了解決這個問題,我們可以使用js防抖函數來實現防止按鈕被頻繁點擊的效果。
function debounceButton(func, wait) { let timeout; return function() { const context = this; const args = arguments; if (timeout) clearTimeout(timeout); const callNow = !timeout; timeout = setTimeout(function() { timeout = null; }, wait); if (callNow) { func.apply(context, args); } }; }
以上代碼中的debounceButton函數接收2個參數:需要防抖的函數以及延遲的毫秒數。返回一個新函數,在調用這個新函數時就會延遲執行傳入的函數。
五、js防抖函數不會重置閉包的變量嗎
在防抖的實現中會使用閉包來緩存定時器,那麼就會引起一個問題:閉包中的變量是不是每次調用防抖函數都會被重置?答案是不會。
當我們多次調用防抖函數時,每一個閉包都會持有一份獨立的timeout變量,它們之間是相互獨立的,互不干擾。這就是js閉包的神奇之處。
六、vue防抖函數
在vue中,可以使用官方提供的工具庫lodash來實現防抖函數。在模板裡面可以使用v-debounce指令來調用防抖函數,在後台API請求中就可以避免頻繁地向服務器請求數據了。
import { debounce } from "lodash"; export default { data() { return { value: "" }; }, methods: { search: debounce(function(query) { console.log(query); }, 500) } };
七、實現一個防抖函數
以下是一個簡單的防抖函數的代碼實現:
function debounce(func, delay) { let timer = null; return function() { const context = this; const args = arguments; clearTimeout(timer); timer = setTimeout(function() { func.apply(context, args); }, delay); }; }
此實現中,第一個參數func是需要防抖的函數,delay是防抖時間。返回一個新函數,調用這個新函數時就會延遲執行傳入的函數,若在延時期間函數被再次觸發,則重新計時,直到延時期滿。
八、js防抖寫法
以下是一種簡單的js防抖寫法:
function debounce(fn, wait) { return function() { clearTimeout(fn.timeoutId); fn.timeoutId = setTimeout(() => { fn.apply(this, arguments); }, wait); }; }
在這種寫法中,將timeoutId作為fn函數的一個屬性以緩存定時器。如果在定時器還沒完成時fn又被執行,則清除之前的計時器重新計時。最後執行函數fn。
九、js防抖和節流代碼
以下是一種防抖和節流代碼結合的寫法:
function throttleDebounce(fn, wait1, isDebounce, wait2) { let timeoutId, lastExecTime; return function() { const context = this; const args = arguments; const elapsedTime = Date.now() - lastExecTime; const execFunc = () => { lastExecTime = Date.now(); fn.apply(context, args); }; if (isDebounce) { clearTimeout(timeoutId); timeoutId = setTimeout(execFunc, wait1); } else if (elapsedTime > wait1) { execFunc(); } else { clearTimeout(timeoutId); timeoutId = setTimeout(execFunc, wait2); } }; }
在這個函數中,有4個參數:需要防抖或節流的函數,防抖時間,是否是防抖模式,節流時間。返回一個新函數,在調用這個新函數時就會延遲執行或者限流後執行傳入的函數。
十、函數節流和函數防抖選取
在實際開發中,如何選擇函數節流和函數防抖呢?
- 如果想要限制函數在一定時間段內只被調用一次,則使用函數節流;
- 如果想要在一段時間內只允許函數執行一次,則使用函數防抖。
舉個例子,如果我們想要執行一個輸入框的驗證,我們可以使用函數防抖,當用戶連續輸入時,不會實時反饋驗證結果,而是在用戶輸入(或停止輸入)一段時間後,才進行驗證。
再舉個例子,當用戶頻繁滾動頁面時,我們可以使用函數節流,每隔一定時間(比如100毫秒)才執行一次處理滾動事件的函數,避免因為這個事件的頻繁觸發導致性能問題。
選擇函數節流還是函數防抖取決於你的場景需求,需要在實際開發中進行權衡取捨。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/249700.html