上週寫了window resize和scroll事件的基本優化,結果微博上交流的人還挺多,你們都提到了一個技術名詞:「throttle」。 javascript
咱們這裏說的throttle就是函數節流的意思。再說的通俗一點就是函數調用的頻度控制器,是連續執行時間間隔控制。主要應用的場景好比: css
有人形象的把上面說的事件形象的比喻成機關槍的掃射,throttle就是機關槍的扳機,你不放扳機,它就一直掃射。咱們開發時用的上面這些事件也是同樣,你不鬆開鼠標,它的事件就一直觸發。回到window resize和scroll事件的基本優化提到的優化: 前端
var resizeTimer = null; $(window).on('resize', function () { if (resizeTimer) { clearTimeout(resizeTimer) } resizeTimer = setTimeout(function(){ console.log("window resize"); }, 400); } );
setTimeout和clearTimeout其實就是一個簡單的 throttle,不少好的控制了resize事件的調用頻度。 java
debounce和throttle很像,debounce是空閒時間必須大於或等於 必定值的時候,纔會執行調用方法。debounce是空閒時間的間隔控制。好比咱們作autocomplete,這時須要咱們很好的控制輸入文字時調用方法時間間隔。通常時第一個輸入的字符立刻開始調用,根據必定的時間間隔重複調用執行的方法。對於變態的輸入,好比按住某一個建不放的時候特別有用。 jquery
debounce主要應用的場景好比: app
這類網上的方法有不少,好比Underscore.js就對throttle和debounce進行封裝。jQuery也有一個throttle和debounce的插件:jQuery throttle / debounce,全部的原理時同樣的,實現的也是一樣的功能。再奉上一個本身一直再用的throttle和debounce控制函數: 函數
/* * 頻率控制 返回函數連續調用時,fn 執行頻率限定爲每多少時間執行一次 * @param fn {function} 須要調用的函數 * @param delay {number} 延遲時間,單位毫秒 * @param immediate {bool} 給 immediate參數傳遞false 綁定的函數先執行,而不是delay後後執行。 * @return {function} 實際調用函數 */ var throttle = function (fn,delay, immediate, debounce) { var curr = +new Date(),//當前事件 last_call = 0, last_exec = 0, timer = null, diff, //時間差 context,//上下文 args, exec = function () { last_exec = curr; fn.apply(context, args); }; return function () { curr= +new Date(); context = this, args = arguments, diff = curr - (debounce ? last_call : last_exec) - delay; clearTimeout(timer); if (debounce) { if (immediate) { timer = setTimeout(exec, delay); } else if (diff >= 0) { exec(); } } else { if (diff >= 0) { exec(); } else if (immediate) { timer = setTimeout(exec, -diff); } } last_call = curr; } }; /* * 空閒控制 返回函數連續調用時,空閒時間必須大於或等於 delay,fn 纔會執行 * @param fn {function} 要調用的函數 * @param delay {number} 空閒時間 * @param immediate {bool} 給 immediate參數傳遞false 綁定的函數先執行,而不是delay後後執行。 * @return {function} 實際調用函數 */ var debounce = function (fn, delay, immediate) { return throttle(fn, delay, immediate, true); };
demo:http://www.css88.com/demo/throttle_debounce/ 優化
更多閱讀: this
http://www.alloyteam.com/2012/11/javascript-throttle/ spa
http://remysharp.com/2010/07/21/throttling-function-calls/
聲明: 本文采用 BY-NC-SA 協議進行受權 | WEB前端開發
轉載請註明轉自《javascript函數的throttle和debounce》