平時咱們在開發中,會常常使用到resize和movesemove事件,這些事件會在短期內頻繁的執行事件綁定程序,咱們知道頻繁的操做DOM會帶來很大的性能消耗,頁面會促發迴流和重繪。有時候頁面會出現卡頓,在IE瀏覽器下可能直接崩潰。這時候節流函數就發揮做用了。瀏覽器
簡單講就是讓一個函數沒法在短期內連續調用,只有當上一次函數執行後過了規定的時間間隔,才能進行下一次該函數的調用。或者說你在操做的時候不會立刻執行該函數,而是等你不操做的時候纔會執行。閉包
經過使用定時器,在操做的時候讓函數延時執行,若是在這個時間內還在操做,則清除原來的定時器,再建立一個新的定時器執行app
最簡單的操做方式,在操做的的時候清除上次的定時器,不操做的過後在執行callBack回調函數
//封裝 /** * @ { Function} callBack 回調程序 */ function throttleFn(callBack){ clearTimeout(method.timer); method.timer=setTimeout(()=>{ method() },100) } //調用 window.onresize=function(){ throttleFn(callBack) }
優點在於把延遲時間當作變量,並且使用閉包保護私有變量,缺點就是雖然使用apply把調用throttleFn時的this上下文傳給執行函數,但畢竟不夠靈活性能
//封裝 /** * @ { Function} callBack 回調程序 * @ { Number } delay 延時時間 * return { Function } */ function thorttleFn(callBack,delay){ var timer=null; return function(){ var context=this; clearTimeout(timer); timer=setTimeout(()=>{ callBack.apply(context,arguments) },delay) } } //調用 window.onresize=thorttleFn(myFunc,300)
拓展深化函數節流this
其實函數節流的出發點,就是讓一個函數不要執行得太頻繁,減小一些過快的調用來節流,減小性能消耗。當你在操做resize和mousemove事件的時候,瀏覽器實際上是有設置一個時間間隔,這個時間是多少咱們不清楚,並且他們沒有提供參數去設置,因此須要咱們在他們的基礎上再去作一些改變。真正的節流應該是在可接受的範圍內儘可能延長這個調用時間,也就是咱們本身控制這個執行頻率,讓函數減小調用以達到減小計算、提高性能的目的。假如原來是16ms執行一次,咱們若是發現resize時每50ms一次也能夠接受,那確定用50ms作時間間隔好一點。code
/** * @ { Function} callBack 回調程序 * @ { Number } delay 延時時間 * @ { Number } intervalTime 間隔時間 * return { Function } */ function thorttleFn(callBack,delay,intervalTime){ var timer=null; // 定時器變量 var time=0; // 時間變量 return function(){ var context=this; var curTime=new Date(); // 當前執行的時間 clearTimeout(timer); // 清除上次的定時器 if(!time){ time=curTime; } // 當前執行時間距離上次執行的時間是否大於等於間隔時間 if(curTime - time >= intervalTime){ time=curTime; callBack.apply(context,arguments) }else{ timer=setTimeout(()=>{ callBack.apply(context,arguments) },delay) } } } //調用 window.onresize=thorttleFn(myFunc,50,300)