js函數的節流與防抖


一、防抖&節流

  在前端開發中有一部分用戶行為會頻繁的觸發事件執行,而對於DOM的操作、資源加載等耗費性能的處理,很可能會導致界面卡頓,甚至瀏覽器奔潰。函數的節流與防抖就是為了解決類似需求而產生的。

  1)節流

    概念:函數的節流就是預定一個函數只有在大於等於執行周期時才會執行,周期內調用不會執行。好像一滴水只有積攢到一定重量才會落下一樣。

    場景:窗口調整(resize)、頁面滾動(scroll)、搶購瘋狂點擊(movedown)

    故事:阿里巴巴月餅門事件,中秋來臨,阿里特意做了一個活動,搶月餅,但是每個人只能搶購一盒,有五位工程師寫了js腳本,類似於12306的搶票軟件,直接刷了一百多盒月餅,結果被開除了四個.其實對於他們來說並不是什么壞事,不知道有多少公司對他們敞開大門~那么如何解決這種問題呢,就用到了函數的節流

  1.1)案例(限時搶購)

    我寫了這樣一個簡單的事件,如下

HTML:
1
<button id='show'>搶購</button> 2 <div id="box">0</div>
JS:
1
let oBtn=document.getElementById('show') 2 let oBox=document.getElementById('box') 3 oBtn.onclick=function(){ 4   oBox.innerText=parseInt(oBox.innerText)+1 5 }

    當我點擊時,每點擊一次,數量增加一,點擊越快,增加越快,效果圖如下:

    

  1.2)腳本攻擊:這種簡單的數量增加很容易遭到腳本的攻擊,從而造成很大的損失。代碼如下

    for(let i=0;i<100;i++){oBtn.click()}

    效果圖如下:

    

  1.3)如何解決(節流)

    上面並不是我們想要的結果,我們想要的是在規定時間內只能執行一次,比如1秒內只能執行一次.無論你點擊多少次.

HTML:
1
<button id='show'>搶購</button> 2 <div id="box">0</div>
 JS:
1
let oBtn=document.getElementById('show'); 2 let oBox=document.getElementById('box'); 3 /* 4 handle:buy函數 5 wait:規定在一秒鍾內只能執行一次 6 */ 7 function throttle (handle, wait) { 8 let lastTime = 0; 9 return function (e) { 10 let nowTime = new Date().getTime() 11 if (nowTime - lastTime > wait) { 12 handle(); 13 lastTime = nowTime; 14 } 15 } 16 } 17 function buy(){ 18 oBox.innerText = parseInt(oBox.innerText)+1 19 } 20 oBtn.onclick = throttle(buy, 1000)

    效果圖如下:

    這樣不僅可以達到想要的效果,還可以阻止惡意腳本的攻擊.

  

  2.防抖

    概念:函數防抖就是函數需要頻繁觸發情況時,只有足夠空閑的時候,才會執行一次。好像公交司機會等人都上車后才會開車一樣.

    場景:實時搜索(keyup)、拖拽(mousemove)

    2.1).案例(實時搜索)

      在之前看一下這個過程圖,百度的實時搜索.

 

      在搜索nba的時候,並不是每輸入一個字符,都會想服務器請求一次,而是在輸入完成后發出一次請求。

HTML:
1
<input type='text' id='ipt'/>
JS:
1
let oIpt = document.getElementById('ipt'); 2 function ajax () { 3 console.log(this.value) 4 } 5 oIpt.oninput = ajax;

      效果圖如下:

    用戶無論輸入多快,都會發出請求,從而去加載服務器資源,對性能有很大的影響.

    2.3)解決(防抖)

 1 let oIpt = document.getElementById('ipt');
 2     let time = null;
 3     function debounce (handle, delay) {
 4         let time = null;
 5         return function () {
 6             let self = this,arg = arguments;
 7             clearTimeout(time);
 8             time = setTimeout(function () {
 9                 handle.apply(self,arg);  //this綁定
10             },delay)
11         }
12     }
13     function ajax (e) {
14         console.log(e,this.value)
15     }
16     oIpt.oninput = debounce(ajax, 1000)  //1s后發出請求

      效果圖:

  這種方法可以解決多次請求的問題,對性能有很大的提高。

  喜歡的小伙伴點個關注哦~我會再接再厲的。

 

    

    

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM