在活動需求中,由於作的狂點小遊戲。在實際體驗中就會出現,頻繁的點擊形成動畫的不連貫,影響用戶體驗。而且再播放音效的時候,若是沒點擊一次就觸發一次音效會形成將聲音壓入到棧中,會持續的播放。所以在這裏的操做作了節流的限制,隔多少秒觸發一次。總結一下節流的實現方法。javascript
節流的原理很簡單:若是你持續觸發事件,每隔一段時間,只執行一次事件。
根據首次是否執行以及結束後是否執行,效果有所不一樣,實現的方式也有所不一樣。
節流的實現方式有兩種主流的實現方式,一種是時間戳,一種是設置定時器。java
本次活動利用的就是該實現方式。
使用時間戳,當觸發事件的時候,咱們取出當前的時間戳,而後減去以前的時間戳(最一開始值設爲0),若是大於設置的時間週期,就執行函數,而後更新時間戳爲當前的時間戳,若是小於就不執行。
具體代碼以下:app
function throttle(fun, wait) { var context,args; var previous = 0; return function () { var now = +new Date();//格式化時間 context = this; args = arguments; if(now - previous > wait){ fun.apply(context,args); previous = now; } } }
這樣寫法適用於,將要執行的函數直接賦值給事件。btn.addEventListener('click',throttle(addSelf,2000),false);由於throttle返回的是一個函數,直接賦值給事件能夠觸發執行。函數
var previous = 0; function throttle(fun, wait) { var context,args; return function () { var now = +new Date();//格式化時間 context = this; args = arguments; if(now - previous > wait){ fun.apply(context,args); previous = now; } } }
將previous提高到外面,寫法就改成btn.addEventListener('click',function () {動畫
throttle(addSelf,2000)(); },false); 這時throttle函數在後面要加小括號直接執行。
當觸發事件的時候,咱們設置一個定時器,再觸發事件的時候,若是定時器存在,就不執行,直到定時器執行,而後執行函數,清空定時器,這樣就能夠設置下個定時器。this
function throttle(fun, wait) { var timeout context,args; return function () { context = this; args = arguments; if(!timeout){ timeout = setTimeout(function () { timeout = null; fun.apply(context,args) },wait) } } }
同理若是用在回調函數中,須要將timeout提到函數外面。
使用定時器有個問題就是點擊不會當即執行,須要延遲設定的時間纔會執行。code
直接上代碼遊戲
var previous = 0; var timeout; function throttle(fun, wait, options) { var context,args; /*var previous = 0;*/ if(!options) options = {}; var later = function () { previous = options.leading === false ? 0 :new Date().getTime(); timeout = null; fun.apply(context,args); if(!timeout) context = args = null; }; var throttled = function () { var now = new Date().getTime(); if(!previous && options.leading === false) previous = now; var remaining = wait - (now - previous); context = this; args = arguments; if(remaining <= 0 || remaining > wait) { if(timeout){ clearTimeout(timeout); timeout = null; } previous = now; fun.apply(context,args); if(!timeout) context = args = null; } else if(!timeout && options.trailing !==false){ timeout = setTimeout(later,remaining) } }; return throttled; } //使用 btn.addEventListener('click',function () { throttle(addSelf,2000,{trailing:false})(); },false);
默認狀況下都是兼顧了第一次點擊當即觸發和最後觸發後執行一次。事件