2011-04-13 35 views
2

每當發生重複事件(點擊「保存」按鈕)但在給定時間段內不觸發它兩次時,我想觸發一個操作(如「更新已保存!」消息)。以最小間隔觸發javascript事件

對於以下情況,我希望excecuteFunction()最多每3秒觸發一次,但如果setInterval在4.5秒後清除,我會仍然希望它在6秒後再次觸發。

var minimumTime = 3000; // minimum ms between events 
function myTimedEvent() { 
    if (lessThanMinimumTime()) 
     // loop through again 
    else { 
     executeFunction(); 
    } 
} 
window.setInterval(myTimedEvent, 500); 

executeFunction()可以在執行創建時間戳和lessThanMinimumTime()可能是時間戳比較當前的時間,然後設定一個子間隔然後您就由executeFunction()清除,如果它是最小的時間範圍之內。

必須有更好的方法。

+0

爲什麼不關閉按鈕然後在定時器中啓用它? – 2011-04-13 21:08:15

+0

按鈕的東西只是一個例子 - 它實際上是一個後臺進程。 – Arrel 2011-04-13 21:33:37

+0

我會考慮在一個callBack類中包裝函數調用,該類包含每個函數的最後一次調用的時間戳......看起來很難但可靠... – Khez 2011-04-13 21:37:25

回答

0

這會觸發事件不會超過每三秒一次(加上executeFunction()執行的時間),但如果事件在最後三秒內觸發,仍然會調用executeFunction()。這是你在找什麼?

var minimumTime = 3000; // minimum ms between events 
var lastFired = null; 
var timer; 
function myEventHandler(){ 
    var now = new Date().getTime(); 
    clearTimeout(timer); 
    if(lessThanMinimumTime()){ 
     timer = setTimeout(myEventHandler, lastFired - now + minimumTime); 
    } else { 
     executeFunction(); 
     lastFired = now; 
    } 
} 

function lessThanMinimumTime(){ 
    if(lastFired == null) return false; 
    return lastFired > new Date().getTime() - minimumTime; 
} 
0

試試這個:

Function.prototype.restrictCallsToInterval = function(sec){ 
    var self = this, 
     last, queued, diff; 

    return function(){ 
     var args = arguments; 
     if(last && !queued && (diff = (new Date().getTime() - last + 1000*sec)) > 0){ 
      // queue this up 
      queued = setTimeout(function(){ 
       self.apply(self, args); 
      }, diff); 

      return; 
     } 

     last = new Date().getTime(); 
     self.apply(self, args); 
    } 
}; 

function doSomething(x){ 
    console.log(x); 
} 

doSomething = doSomething.restrictCallsToInterval(3); 
doSomething(22); 
doSomething(23); 
+0

這是最好的答案 - 它並不簡單,但它隱藏了所有的醜陋。但是......它也不起作用。如果你第三次打電話給doSomething(24),它會立即觸發第三個電話,只會提示第二個電話。 – Arrel 2011-04-14 17:30:35

0

好吧,你自找的「更好的方式」 - 我不認爲有任何真正的更好方式,但是這是最簡單的方法,我可以想想:

var minimumTime = 3000; // minimum ms between events 
var canFireEvent = true; 
function myTimedEvent() { 
    if (canFireEvent) { 
     canFireEvent = false; 
     window.setTimeout(function() { 
      canFireEvent = true; 
     }, minimumTime); 
     executeFunction(); 
    } 
} 

使用一個單一的布爾標誌。沒有與日期混淆。

Proof of concept
(雖然定時器間隔爲1秒,但功能每3秒鐘執行一次)

+0

這適用於最小時間間隔,但不能確保上次事件的觸發:如果我們在4.5秒後切斷setInterval,則在6秒後不會觸發。 – Arrel 2011-04-14 17:26:05