javascript的防抖和節流你瞭解嗎
一:為什麼需要防抖與節流
防抖和節流都是為了解決短時間內大量觸發某函式或者事件而導致的效能問題,比如在
1.使用者體驗上,觸發頻率過高導致的響應速度跟不上觸發頻率,出現延遲,假死,卡頓的現象
2.伺服器上:加重伺服器壓力
二:防抖
防抖是當事件或函式被觸發後,延遲n秒後在執行回撥,如果在這n秒內事件或函式又被觸發,則重新計時,直到n秒內沒有觸發事件或函式,則執行回撥函式
圖文解釋:
(回城的時間就相當於延遲時間,如果在回城的時間內再次觸發回城則重新倒計時回城時間)
案例:表單輸入框事件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>Document</title> </head> <body> <input type="text" class="serach"> <script> let serach = document.getElementsByClassName('serach')[0] // console.log(serach); serach.addEventListener('input',function() { console.log('向後端發起了請求!'); }) </script> </body> </html>
執行:
可以看出當我每次輸入一個數字的時候都發起了請求,這是不符合專案要求和這非常消耗伺服器的效能,我們應該在使用者在輸入內容後的一段時間內如果使用者不再輸入內容再發起請求,使用者如果在這一段時間內再次輸入,則繼續等待使用者在一段時間內不再輸入內容後再發起請求。
使用防抖優化:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible"www.cppcns.com content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>Document</title> </head> <body> <input type="text" class="serach"> <script> let serach = dohttp://www.cppcns.comcument.getElementsByClassName('serach')[0] // console.log(serach); http://www.cppcns.comlet timer = null; //宣告一個用於防抖的定時器變數timer serach.addEventListener('input',function() { clearTimeout(timer) //如果在定時器的時間間隔內再次觸發事件則清除定時器,重新執行新的定時器函式 // 定時器函式 timer = setTimeout(function() { console.log('向後端發起了請求!'); },500) }) </script> </body> </html>
執行:
如果在500毫秒內呼叫多次,只會執行最後一次
可以看出在輸入完內容後的500毫秒後才發起請求
防抖的應用場景:
1.使用者在輸入框連續輸入一串字元時,可以通過放抖策略,只在輸入完後,才執行查詢的請求,這樣可以有效減少請求次數,節約請求資源。(也可以用節流)
2.登入、發簡訊等按鈕避免使用者點選太快,以致於傳送了多次請求,需要防抖
3.調整瀏覽器視窗大小時,resize 次數過於頻繁,造成計算過多,此時需要一次到位,就用到了防抖
4.文字編輯器實時儲存,當無任何更改操作一秒後進行儲存
三、節流
控制事件發生的頻率從而達到減少一段時間內事件的觸發頻率,如控制為1s發生一次,甚至1分鐘發生一次。
圖文解釋:
(當玩射擊遊戲時,無論你手點的有多快射出的彈還是有規律的發出(比如0.5發出一個彈))
案例:獲取滑鼠的最終座標
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>Document</title> <style> .app { width: 800px; height: 800px; background-color: pink; } </style> </head> <body> <div class="app"> </div> <script> let app = document.getElementsByClassName('app')[0] app.addEventListener('mousemove',function(e) { console.log(`x座標${e.pageX},y座標${e.pageY}`); }) </script> </body> </html>
執行:
可以看出每次滑鼠移動都執行函式,大大消耗效能,我們可以利用節流策略,一秒內只執行一次來節流
節流優化:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>Document</title> <style> .app { width: 800px; height: 800px; background-color: pink; } </style> </head> <body> <div class="app"> </div> <script> let app = document.getElementsByClassName('app')[0] let timer = true; //定義一個節流閥變數來控制節流閥為關閉還是開啟狀態,預設為開啟 app.addEventListener('mousemove',function(e) { if (!timer) { return //判斷節流閥是否關閉,如果節流閥還是false(關閉狀態),則證明上次的函式未執行完,直接退出函式 } timer = false; //設定節流閥為false,如果定時器函式沒有設定為true,則定時器函式沒執行,節流閥一直為關(false) setTimeouGvXUIt(function() { console.log(`x座標${e.pageX},y座標${e.pageY}`) timer = true //定時器函式已經執行,設定節流閥為true },500) }) </script> </body> </html>
執行效果:
使用節流後,座標列印次數明顯變少,節流效果達成
四.防抖和節流的區別:
防抖:如果事件被頻繁觸發,防抖能保證只有最後一次觸發生效!前面N多次的觸發都會被忽略!
節流:如果事件被頻繁觸發,節流能夠減少事件觸發的頻率,因此,節流是有選擇性地執行一部分事件,單位時間內事件只能觸發一次
總結
本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注我們的更多內容!