事件被觸發通過單位時間(delay)後再執行回調,若是在單位時間內又被觸發,則從新計時。html
const debounce = (cb, delay = 1000) => { let timer = null; return function (...args) { const context = this; if (timer) clearTimeout(timer); timer = setTimeout(() => { cb.apply(context, args); timer = null; }, delay); } }
若延遲delay設置爲1000(默認值),則cb(回調函數)只會在中止觸發1s後執行,若是一直不斷地觸發,則回調函數始終不執行。app
下面是一個簡單的使用示例,後續介紹的防抖和節流函數的使用方式也是類似的。dom
const callback = () => { console.log(Math.random()); } const handle = debounce(callback, 1000); window.addEventListener('scroll', handle);
const debounceImmediate = (cb, delay = 1000, immediate = true) => { let timer = null; return function (...args) { const context = this; const execNow = immediate && !timer; if (timer) clearTimeout(timer); timer = setTimeout(() => { cb.apply(context, args); timer = null; }, delay); execNow && cb.apply(this, args); } }
當設置immediate=true(默認值)、delay=1000(默認值)時,第一次觸發會當即執行回調函數。後續執行和普通的防抖函數同樣,只有在中止觸發1s後回調函數纔會執行,若是仍是一直不斷地觸發,則回調函數始終不執行。函數
規定在單位時間(delay)內,只能觸發一次函數。若是單位時間內屢次觸發函數,只會執行一次回調。this
const throttleUseTimeStamp = (cb, delay = 1000) => { let startTime = Date.now(); return function(...args) { const context = this; const now = Date.now(); if (now - startTime >= delay) { cb.apply(context, args); startTime = Date.now(); } } }
若delay=1000,則在1s內只會執行一次回調函數。spa
const throttleUseTimer = (cb, delay) => { let timer = null; return function(...args) { const context = this; if (!timer) { timer = setTimeout(() => { cb.apply(context, args); timer = null; }, delay); } } }
若delay=1000,則在1s內只會執行一次回調函數。code
const throttleExecMore = function(cb, delay) { let timer = null; let startTime = Date.now(); return function(...args) { const curTime = Date.now(); const remaining = delay - (curTime - startTime); const context = this; timer && clearTimeout(timer); if (remaining <= 0) { // 第一次觸發執行 cb.apply(context, args); startTime = Date.now(); } else { // 最後一次觸發也會執行 timer = setTimeout(() => { cb.apply(context, args); timer = null; }, remaining); } } }
第一次觸發會當即執行回調函數,最後一次觸發也會執行一次回調函數。htm
將前面介紹的5種防抖和節流函數分別應用在5個輸入框的onChange事件的監聽上,delay值統一設置爲1000,快速輸入1111獲得結果以下:
徹底符合咱們前面的分析。blog
若是不加防抖、節流控制,獲得結果將是:事件
1 11 111 1111
觸發了4次回調函數。
體驗防抖和節流 (http://47.92.166.108:3000/blog/index.html#/tutorials/throttle-and-debounce)
體驗網址二維碼: