javascript
JS----JavaScript中防抖和节流知识概述
防抖和節(jié)流
瀏覽器的 resize、scroll、keypress、mousemove 等事件在觸發(fā)時(shí),會不斷地調(diào)用綁定在事件上的回調(diào)函數(shù),極大地浪費(fèi)資源,降低前端性能。為了優(yōu)化體驗(yàn),需要對這類事件進(jìn)行調(diào)用次數(shù)的限制。
防抖(debounce)
作用是在短時(shí)間內(nèi)多次觸發(fā)同一個(gè)函數(shù),只執(zhí)行最后一次,或者只在開始時(shí)執(zhí)行。
以用戶拖拽改變窗口大小,觸發(fā) resize 事件為例,在這過程中窗口的大小一直在改變,所以如果我們在 resize 事件中綁定函數(shù),這個(gè)函數(shù)將會一直觸發(fā),而這種情況大多數(shù)情況下是無意義的,還會造成資源的大量浪費(fèi)。
這時(shí)候可以使用函數(shù)防抖來優(yōu)化相關(guān)操作:
// 普通方案 window.addEventListener('resize', () => {console.log('trigger'); })優(yōu)化方案:
// debounce 函數(shù)接受一個(gè)函數(shù)和延遲執(zhí)行的時(shí)間作為參數(shù) function debounce(fn, delay){// 維護(hù)一個(gè) timerlet timer = null;return function() {// 獲取函數(shù)的作用域和變量let context = this;let args = arguments;clearTimeout(timer);timer = setTimeout(function(){fn.apply(context, args);}, delay)} } function foo() {console.log('trigger'); } // 在 debounce 中包裝我們的函數(shù),過 2 秒觸發(fā)一次 window.addEventListener('resize', debounce(foo, 2000));- 在 resize 事件上綁定處理函數(shù),這時(shí) debounce 函數(shù)會立即調(diào)用,實(shí)際上綁定的函數(shù)時(shí) debounce
函數(shù)內(nèi)部返回的函數(shù)。 - 每一次事件被觸發(fā),都會清除當(dāng)前的 timer 然后重新設(shè)置超時(shí)調(diào)用。
- 只有在最后一次觸發(fā)事件,才能在 delay 時(shí)間后執(zhí)行。
我們也可以為 debounce 函數(shù)加一個(gè)參數(shù),可以選擇是否立即執(zhí)行函數(shù)
function debounce(func, delay, immediate){var timer = null;return function(){var context = this;var args = arguments;if(timer) clearTimeout(timer);if(immediate){var doNow = !timer;timer = setTimeout(function(){timer = null;},delay);if(doNow){func.apply(context,args);}}else{timer = setTimeout(function(){func.apply(context,args);},delay);}} }節(jié)流(throttle)
類似于防抖,節(jié)流是在一段時(shí)間內(nèi)只允許函數(shù)執(zhí)行一次。
應(yīng)用場景如:輸入框的聯(lián)想,可以限定用戶在輸入時(shí),只在每兩秒鐘響應(yīng)一次聯(lián)想。
可通過時(shí)間戳和定時(shí)器來實(shí)現(xiàn)。
時(shí)間戳實(shí)現(xiàn):
var throttle = function(func, delay){var prev = Date.now();return function(){var context = this;var args = arguments;var now = Date.now();if(now-prev>=delay){func.apply(context,args);prev = Date.now();}} }定時(shí)器實(shí)現(xiàn):
var throttle = function(func, delay){var timer = null;return function(){var context = this;var args = arguments;if(!timer){timer = setTimeout(function(){func.apply(context, args);timer = null;},delay);}} }區(qū)別在于,使用時(shí)間戳實(shí)現(xiàn)的節(jié)流函數(shù)會在第一次觸發(fā)事件時(shí)立即執(zhí)行,以后每過 delay 秒之后才執(zhí)行一次,并且最后一次觸發(fā)事件不會被執(zhí)行;而定時(shí)器實(shí)現(xiàn)的節(jié)流函數(shù)在第一次觸發(fā)時(shí)不會執(zhí)行,而是在 delay 秒之后才執(zhí)行,當(dāng)最后一次停止觸發(fā)后,還會再執(zhí)行一次函數(shù)。
總結(jié)
以上是生活随笔為你收集整理的JS----JavaScript中防抖和节流知识概述的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iOS 13.4测试版更新内容汇总及升级
- 下一篇: JS----javascript中使用r