一文看懂如何簡(jiǎn)單實(shí)現(xiàn)節(jié)流函數(shù)和防抖函數(shù)
前言
在日常開發(fā)中有很多場(chǎng)景我們都需要用到節(jié)流函數(shù)和防抖函數(shù),比如:實(shí)現(xiàn)輸入框的模糊查詢因?yàn)樾枰喸僡jax,影響瀏覽器性能,所以需要用到節(jié)流函數(shù);實(shí)現(xiàn)手機(jī)號(hào)、姓名之類的的驗(yàn)證,往往我們只需要驗(yàn)證一次,這個(gè)時(shí)候我們就需要用到防抖函數(shù);但是網(wǎng)上的很多資料都是不夠具體和便于理解。今天自己翻閱了一些資料之后,來簡(jiǎn)單的談?wù)勎覍?duì)節(jié)流函數(shù)和防抖函數(shù)的理解,希望能幫助大家理解;
節(jié)流函數(shù)
顧名思義,就是節(jié)省流量節(jié)省內(nèi)存性能的一種函數(shù),可以理解為是一種性能優(yōu)化方案;
舉個(gè)例子:一個(gè)水龍頭一直在滴水,可能一次性會(huì)滴很多水,但是我們想控制它的頻率 ,讓它每1000毫秒滴一滴水,這個(gè)時(shí)候我們就可以用到節(jié)流函數(shù)來進(jìn)行控制(簡(jiǎn)單可以理解為類似于周期性定時(shí)器)
js代碼(可直接復(fù)制到編輯器上看效果):
//首先定義一個(gè)全局變量 var canRun = true; //當(dāng)瀏覽器窗口大小發(fā)生變化也就是重新計(jì)算窗口大小的時(shí)候觸發(fā) window.onresize = function(){ // 取反,canRun為false的情況下 if(!canRun){ //直接return,后面的代碼不執(zhí)行 return } //走到這來就是canRun為true的情況,然后進(jìn)行賦值為false canRun = false //設(shè)置一個(gè)定時(shí)器進(jìn)行輪詢操作 setTimeout( function () { //這是要做的事情 console.log("函數(shù)節(jié)流") //最后記得重新賦值true繼續(xù)讓他取反 canRun = true //每隔1000毫秒也就是1秒鐘就執(zhí)行一次 }, 1000) }
效果圖如下:
防抖函數(shù)
防抖函數(shù)和節(jié)流函數(shù)很類似,但是稍有區(qū)別,防抖函數(shù)的定義是當(dāng)事件觸發(fā)完成之后再延遲觸發(fā),并且只觸發(fā)一次;如果在觸發(fā)完成之前再次觸發(fā),則會(huì)再次刷新延遲;簡(jiǎn)單理解為(如果事件不觸發(fā)即不執(zhí)行,并且只會(huì)執(zhí)行一次,就是定時(shí)器最后走的那一次)
舉個(gè)例子:假如有個(gè)彈簧,你一直往下按壓只要你不松手就是不會(huì)彈出的,彈簧只有在你松手的那一瞬間才會(huì)彈出去;防抖函數(shù)也是如此,只要事情觸發(fā)沒有結(jié)束是不會(huì)執(zhí)行的,只有在事件觸發(fā)結(jié)束后延遲執(zhí)行一次;
js代碼(可直接復(fù)制到編輯器上看效果):
//定義方法即要做的事情 function fun(){ console.log('onresize') } //定義事件觸發(fā)要執(zhí)行的方法,兩個(gè)參數(shù)分別是傳入的要做的事情和定時(shí)器的毫秒數(shù) function debounce(fn,delay){ //定義一個(gè)變量作為等會(huì)清除對(duì)象 var handle; //這里用到了閉包,一個(gè)函數(shù)里面return另一個(gè)函數(shù),變量相互簽引導(dǎo)致垃圾回收機(jī)制不會(huì)銷毀handle變量 return function(){ //在這里一定要清除前面的定時(shí)器,然后創(chuàng)建一個(gè)新的定時(shí)器 clearTimeout(handle) //最后這個(gè)定時(shí)器只會(huì)執(zhí)行一次也就是事件觸發(fā)完成之后延遲500毫秒再觸發(fā)(這里的變量賦值是跟定時(shí)器建立連接,進(jìn)行地址賦值,一定要重新賦值給handle handle=setTimeout(function(){ fn() },delay) } } //給瀏覽器添加監(jiān)聽事件resize window.addEventListener('resize', debounce(fun, 500));
效果圖如下:
總結(jié):
1.防抖函數(shù)和節(jié)流函數(shù)都是用來提升性能優(yōu)化及用戶體驗(yàn)的一種方案;
2.防抖函數(shù)只會(huì)執(zhí)行一次,且是最后觸發(fā)的那一次,而節(jié)流函數(shù)會(huì)規(guī)律性的執(zhí)行多次;
好了,以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
原生js實(shí)現(xiàn)倒計(jì)時(shí)--2018
本文主要介紹了原生js實(shí)現(xiàn)倒計(jì)時(shí)--2018的示例代碼,具有很好的參考價(jià)值,下面跟著小編一起來看下吧2017-02-02javascript 函數(shù)的暫停和恢復(fù)實(shí)例詳解
這篇文章主要介紹了javascript 函數(shù)的暫停和恢復(fù),結(jié)合實(shí)例形式詳細(xì)分析了javascript 函數(shù)的暫停和恢復(fù)相關(guān)原理、實(shí)現(xiàn)方法及操作注意事項(xiàng),需要的朋友可以參考下2020-04-04javascript 無限聯(lián)動(dòng)菜單效果代碼
javascript 無限聯(lián)動(dòng)菜單效果代碼,需要的朋友可以參考下。2010-04-04JS基于面向?qū)ο髮?shí)現(xiàn)的拖拽庫(kù)實(shí)例
這篇文章主要介紹了JS基于面向?qū)ο髮?shí)現(xiàn)的拖拽庫(kù),以實(shí)例形式分析了JavaScript設(shè)置水平、垂直拖拽及限制拖拽范圍的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09JS+HTML5 FileReader實(shí)現(xiàn)文件上傳前本地預(yù)覽功能
這篇文章主要為大家詳細(xì)介紹了JS+HTML5 FileReader實(shí)現(xiàn)文件上傳前本地預(yù)覽功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07js實(shí)現(xiàn)的早期滑動(dòng)門菜單效果代碼
這篇文章主要介紹了js實(shí)現(xiàn)的早期滑動(dòng)門菜單效果代碼,涉及javascript數(shù)組遍歷及通過鼠標(biāo)事件動(dòng)態(tài)改變頁面元素屬性的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-08-08