一、防抖&節流
在前端開發中有一部分用戶行為會頻繁的觸發事件執行,而對於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后發出請求
效果圖:
這種方法可以解決多次請求的問題,對性能有很大的提高。
喜歡的小伙伴點個關注哦~我會再接再厲的。