<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
函數防抖動(debounce):防止在短時間內過於頻繁的執行相同的任務。 當短時間內的頻繁是不必要的時候,就可以考慮去抖動,避免資源浪費,或造成不好體驗。
函數防抖動的原理,主要是利用一次性定時器,延遲任務的執行,在延遲這段時間內, 如果任務再次被觸發,則通過 clearTimeout 銷燬上一次產生的定時器, 因為定時器的被銷燬,之前被延遲執行的任務也會隨之被取消執行。 這樣就實現了在一定時間內,只執行一次任務。這一次的執行通常是最後一次的觸發, 因為此前的觸發因為定時器的銷燬而被取消了。
多次觸發只執行最後一次或許就是和“節流”概念的區別?它兩在作用上挺像的,在具體實現上略有不同。 函數防抖(debounce)是短時間內連續多次觸發,但只執行最後一次,即是說將多次執行變成了只執行最後一次,執行次數減少。 而節流(throttle)是將短時間的多次執行,變成每隔一段時間執行一次。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>防抖動 Demo</title> </head> <body> <h1>防抖動 Demo</h1> <label> <span>輸入暱稱:</span> <input oninput="inputChange(event.data)"></input> </label> <script> let timer = null function inputChange (data) { // 不做防抖動會頻繁觸發校驗,例如連續的輸入兩個字可能會觸發6-7次, // 這種頻繁程度可能不是必要的,當頻繁不是必要的,那麼就是資源的浪費。 // validatePhone(data) // 防抖處理,連續正常的輸入同樣的兩個字,只會觸發一次校驗任務。 clearTimeout(timer) timer = setTimeout(() => { validatePhone(data) }, 1000) } function validatePhone (data) { let flag = true const regPhone = /^1d{10}$/ if (!regPhone.test(data)) { flag = false console.log('校驗內容:' + data + '。手機號不正確,請輸入1開頭的11位手機號') } return flag } </script> </body> </html>
當任務在短時間內被頻繁執行,而這種頻繁不是必要的,或不是想要的,就可以考慮使用防抖。 下面是一些場景例子:
①監聽卷軸實現左側內容和右側導航關聯,卷軸的頻繁程度很高, 而這種頻繁程度可能不是我們想要的,此時就可以考慮使用防抖。
例如我在 JavaScript實現內容捲動與導航標籤互動關聯方案中就使用了防抖。
// 監聽卷軸 window.addEventListener("scroll", function (e) { // 防抖動處理 clearTimeout(that.timeout) this.timeout = setTimeout(() => { that.activeNavNode(e) }, 100) });
②表單輸入的一些監聽事件,例如 oninput 等。
③一些元件庫的內容變化監聽,例如 el-tree 的 @check-change 事件, 當選擇祖先級的選項時,因為包含了選中其子孫項,@check-change 會被頻繁觸發, 如果這個選項變化關聯介面,那麼這種頻繁可能不是必要的。
下面是一個範例:
<el-tree ref="tree" :data="treeData" show-checkbox @check-change="handleCheckChange"> </el-tree>
handleCheckChange (data, checked, indeterminate) { // 簡單的防抖動處理 clearTimeout(this.timeout) this.timeout = setTimeout(() => { let checkedKeys = this.$refs.tree.getCheckedKeys() // 處理相關業務,例如根據選中的條件,觸發介面查詢 // this.$emit('checkChange', checkedKeys.join(';')) }, 300) },
④監聽瀏覽器視窗變化 window.onresize,例如在 echarts 的應用中, 預設瀏覽器視窗大小改變 echarts 檢視佈局是不會做響應式改變的, 那麼就需要通過監聽瀏覽器視窗大小改變然後去重置 echarts 實現佈局的改變。 實踐發現,調整一下瀏覽器視窗大小,會非常多次觸發 onresize, 但如果我們也跟著去多次重置 echarts.resize(),這不僅不是必要的, 而且還會造成閃爍頻繁,卡頓等不好的體驗,以及效能浪費。此時適合用防抖動處理。
下面是一個範例:
// 裝置視口大小改變時,重置 echarts let timer = null window.onresize = function () { // 簡單的防抖動處理 clearTimeout(timer) timer = setTimeout(() => { console.log(timer) chart.resize() }, 500) }
也可以考慮使用閉包的方式,而不必在外面宣告 timer,例如這樣
// 也可以考慮用閉包的方式 window.onresize = this.debounce(() => { chart.resize() }, 500) function debounce (fn, delay = 1000) { let timer = null return () => { if (timer) clearTimeout(timer) timer = setTimeout(fn, delay) } }
⑤滑鼠事件,例如拖拽等的監聽等,出於準確性和及時性, 他們的監聽響應十分細密,而當這種頻繁在業務上可能不是必要的,那麼也可以考慮使用防抖動技術。
到此這篇關於JavaScript函數防抖動debounce的文章就介紹到這了,更多相關JS防抖動內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45