在開發中經常碰到需要基於監聽滾動條、視窗放大縮小、滑鼠移動的需求,應該都能發現如果不加防抖或是節流函式,會使得這個***頻繁的觸發,可能會導致失幀的情況下面會一步步的漸進式的去實現防抖功能,原理其實很簡單
<
!doctype html>
"utf-8"
>
<
/title>
"text/css"
>
* #box
<
/style>
<
/head>
"box"
>
0<
/div>
<
/body>
<
/html>
先看一下沒使用防抖時觸發的頻率var num =0;
var dom = document.
getelementbyid
("box");
function
mouse()
dom.
addeventlistener
("mousemove"
, mouse)
;<
/script>
可以看到觸發的頻率是很頻繁的
接下來按著需求一步步實現防抖函式
第一步實現 ,當滑鼠移動時無論怎麼移動都不觸發,停止移動一秒後再觸發
dom.
addeventlistener
("mousemove"
,debounce
(mouse,
1000))
;function
debounce
(func, wait
)}
這一步應該很好理解,利用閉包快取timer變數,每次觸發都會生成乙個計時器任務使用timer變數儲存定時器的id並且清除這個任務,停止移動時就只剩下乙個定時器任務
看下效果,很讚
立即執行版的防抖函式
這個版本就是我一移動就直接執行函式,繼續移動是不管用的,必須要停下一定的時間是再移動才觸發可能有一些提交表單的按鈕也會需要用到,按了之後立即提交表單驗證,再觸發必須要等一段時間,當然有驗證的話按完清空表單或者禁用按鈕都是可選的
dom.
addeventlistener
("mousemove"
,debounce
(mouse,
1000))
;function
debounce
(func, wait
),wait)
}}
這裡的執行原理:
當第一次執行防抖函式if(timer) cleartimeout(timer);
這時timer還是undefined 所以不會執行清除語句
if(!timer) func();
第一次執行timer是undefined在前面加上邏輯非!就變為true直接執行該語句,也就是執行函式
執行定時器並給 timer賦值,這個值是定時器任務的id,先說滑鼠一直移動的情況:
當滑鼠一直移動時,timer是有值的,第二次觸發再說一下滑鼠不移動時的執**況if(timer) cleartimeout(timer);
會取消對應的定時器任務,這裡需要注意的一點是雖然任務被取消但是timer變數儲存的還是該任務的id。所以不會執行
if(!timer) func();
,因為timer是有值的接下來繼續新增計時器任務,並給timer變數賦上相對應的任務id
當滑鼠不在移動的情況下,這是定時器任務執行下乙個,這個任務會在指定的時間下給timer賦值null看下效果,是我們要的沒錯了再次移動是就會像上面說的一樣立即執行
結合一下兩個模式,根據傳第三個引數來按條件執行
dom.
addeventlistener
("mousemove"
,debounce
(mouse,
1000
,false))
;function
debounce
(func, wait, immediate
),wait)
}else
}}
是不是超級簡單
function
mouse(e
)dom.
addeventlistener
("mousemove"
,debounce
(mouse,
1000
,false))
;function
debounce
(func, wait, immediate
),wait)
}else
, wait);}
}}
JS系列之防抖節流
函式節流和函式防抖,兩者都是優化高頻率執行js 的一種手段。函式節流 throttle 與 函式防抖 debounce 都是為了限制函式的執行頻次,以優化函式觸發頻率過高導致的響應速度跟不上觸發頻率,出現延遲,假死或卡頓的現象。函式節流是指一定時間內執行的操作只執行一次,也就是說即預先設定乙個執行週...
JS之防抖與節流
首先,我們給滾動事件新增乙個函式,讓他列印當前滾動條的位置,功能就是監聽滾動條距離頂部的位置。function showtop window.onscroll showtop 但此時我們發現,我只是滾動了一下,結果列印了好多個值,如下圖所示,該事件多次被觸發,頻率之高容易使得瀏覽器崩潰 所以我們希望...
js優化之防抖節流
應用場景 搜尋框 滾動條的監聽事件處理,防止每輸入乙個字 滾動螢幕,都會觸發事件處理,造成效能浪費。短時間內大量觸發同一事件,只會執行一次函式,實現原理為設定乙個定時器,約定在xx毫秒後再觸發事件處理,每次觸發事件都會重新設定計時器,直到xx毫秒內無第二次操作 引數1為觸發事件函式,參2位延遲時間 ...