本文主要介紹了javascript函數的節流[throttle]與防抖[debounce ],詳細的介紹了節流與防抖的原理和範例,具有一定的參考價值,有興趣的可以了解一下,希望能幫助大家。
防手震與節流
視窗的resize、scroll,輸入框內容校驗等操作時,如果這些操作處理函數較為複雜或頁面頻繁重渲染等操作時,如果事件觸發的頻率無限制,會加重瀏覽器的負擔,導致使用者體驗非常糟糕。此時我們可以採用debounce(防抖)和throttle(節流)的方式來減少觸發的頻率,同時又不影響實際效果。
這兩個東西都是為了專案優化而出現的,官方是沒有具體定義的,他們的出現主要是為了解決一些短時間內連續執行的事件帶來性能上的不佳和內存的消耗巨大等問題;
像這類事件一般像scroll keyup mousemove resize等等,短時間內不斷的觸發,在性能上消耗是非常大的,尤其是一些改變DOM結構的操作;
節流[throttle]與防手震[debounce]非常相似,都是讓上述這類事件在規定的事件從不斷的去觸發更改成為規定的時間內觸發多少次;
節流[throttle]
節流通俗來解釋就比如我們水龍頭放水,閥門一打開,水嘩嘩的往下流,這個秉著勤儉節約的優良傳統美德,我們要把水龍頭關小點,最好是如我們心意按照一定規律在某個時間間隔內一滴一滴的往下滴,這,,,好吧這就是我們節流的概念;
換成函數來說,使用setTimeout方法,給定兩個時間,後面的時間減去前面的時間,到達我們給定的時間就去觸發一次這個事件,這麼說太籠統的,我們看下面的函數,這裡我們以【scroll】為例;
/** 样式我就顺便写了 **/ <style> *{padding:0;margin:0;} .scroll-box{ width : 100%; height : 500px; background:blue; overflow : auto; } .scroll-item{ height:1000px; width:100%; } </style>
------------------------
/** 先给定DOM结构;**/ <p class="scroll-box"> <p class="scroll-item"></p> </p>
------------------------
/**主要看js,为了简单我用JQ去写了**/ <script> $(document).ready(function(){ var scrollBox = $('.scroll-box'); //调用throttle函数,传入相应的方法和规定的时间; var thro = throttle(throFun,300); //触发事件; scrollBox.on('scroll' , function(){ //调用执行函数; thro(); }) // 封装函数; function throttle(method,time){ var timer = null; var startTime = new Date(); return function(){ var context = this; var endTime = new Date(); var resTime = endTime - startTime; //判断大于等于我们给的时间采取执行函数; if(resTime >= time){ method.call(context); //执行完函数之后重置初始时间,等于最后一次触发的时间 startTime = endTime; } } } function throFun(){ console.log('success'); } }) </script>
透過以上的函數,我們就可以做到節流的效果,在規定的每300毫秒觸發一次,當然時間可以自訂,根據需求來;
防抖[debounce ]
寫程式碼之前,我們先清楚一下防手震的概念,不知道大家有沒有做過電腦端兩邊懸浮廣告視窗的這麼東西,當我們拖曳滾動條的時候,兩邊的廣告窗口會因為滾動條的拖動,而不斷的嘗試著去居於中間,然後你就會看到這兩個窗口,不停的抖啊抖;
一般這種就叫抖動了,我們要做的就是防止這種抖動,稱為防抖[debounce ];
那這裡防抖思想就是當我們拖曳完成之後,兩邊的視窗位置再重新去計算,這樣,就會顯得很平滑,看著很舒服了,最主要的操作DOM結構的次數就大大減少了;
優化了頁面性能,降低了內存消耗,不然你像IE這種比較老點版本的瀏覽器,說不定就直接給你蹦了
用書面一點的說法就是,在某個事件沒有結束之前,函數不會執行,當結束之後,我們給定延時時間,然他在給定的延時時間之後再去執行這個函數,這就是防手震函數;
#來看程式碼:
//将上面的throttle函数替换为debounce函数; function debounce(method,time){ var timer = null ; return function(){ var context = this; //在函数执行的时候先清除timer定时器; clearTimeout(timer); timer = setTimeout(function(){ method.call(context); },time); } }
思路就是在函數執行之前,我們先清除定時器,如果函數一直執行,就會不斷的去清除定時器中的方法,知道我們操作結束之後,函數才會執行;
其實書寫的方式有很多,主要還是思路的問題,大家寫的多了,自然就知道了;
用途
當我們做keyup像後台請求檢驗的時候,可以使用防手震函數,不然我們每按一次鍵盤就請求一次,請求太頻繁,這樣當我們結束按鍵盤的時候再去請求,請求少很多了,性能自然不用說;
resize 視窗大小調整的時候,我們可以採用防手震技術也可以使用節流;
mousemove 滑鼠移動事件我們既可以採用防手震也可以使用節流;
scroll 捲軸觸發的事件,當然既可以採用防抖也可以採用節流;
連續高頻發的事件都可以採用這兩種方式去解決,優化頁面效能;
具體的採用哪一種較為合適,主要還是看你的業務需求。
相關推薦:
#以上是詳解javascript函數的節流與防手震的詳細內容。更多資訊請關注PHP中文網其他相關文章!