开发者

Trigger javascript events with a minimum interval

开发者 https://www.devze.com 2023-02-25 04:32 出处:网络
I want to trigger an action (like an \"Update saved!\" message) whenever a repeated event occurs (hitting the \"save\" button) but not trigger it twice within a given time period.

I want to trigger an action (like an "Update saved!" message) whenever a repeated event occurs (hitting the "save" button) but not trigger it twice within a given time period.

For the following, I want excecuteFunction() to trigger at most once every 3 seconds, but if the setInterval is cleared after 4.5 seconds I would still want it to trigger again after 6 seconds.

var minimumTime = 3000; // minimum ms between events
function myTimedEvent() {
    if ( lessThanMinimumTime() )
        // loop through again
    else {
        executeFunction();
    }
}
window.setInterval(myTimedEven开发者_运维知识库t, 500);

executeFunction() could create a timestamp on execution, and lessThanMinimumTime() could compare that timestamp to the current time, then set a sub-interval that's then cleared by executeFunction() if it's inside the minimum time range.

There must be a better way.


This will fire the event no more than once every three second (plus the time it takes executeFunction() to execute), but will still call executeFunction() if the event fires during the last three seconds. Is this what you're looking for?

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;
}


try this:

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);


Well, you asked for "better way" - I don't think there is really any better way, but this is the most simple way I can think of:

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

Using one single boolean flag. No messing with dates.

Proof of concept.
(Function executed every 3 seconds although the timer interval is 1 second)

0

精彩评论

暂无评论...
验证码 换一张
取 消