Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React to an event only once every 5 seconds

Tags:

jquery

I'm trying to run a function using setInterval() and click. I want run the function somefunction() only once in every five seconds when i click.

Here is my code:

function somefunction(){ // do something }

setInterval(function(){
  $('#division').one("click",function(){
    somefunction();
  });
}, 5000);

The issue here is, the event setInterval() is queuing up and say after 30 secs the function somefunction(); runs upto 6 times (for 6 clicks).

But I want it to run only once and wait for next 5 seconds.

I have tried .stop(), .dequeue() and .clearqueue() although nothing worked.

Thanks for your help!

like image 261
Yesh Avatar asked Feb 17 '23 18:02

Yesh


2 Answers

How about ignoring every click that has been less than 5 seconds ago?

function somefunction() { /* do something */ }

$('#division').on("click", function () {
  var lastClicked = $(this).data("lastClicked") || 0;

  if (new Date() - lastClicked >= 5000) {
    $(this).data("lastClicked", new Date());
    somefunction();
  }
});

Alternatively, schedule the click in accordance to the last one, ignore all clicks as long as an action is scheduled:

function somefunction() { /* do something */ }

$('#division').on("click", function () {
  var $this = $(this),
      lastClicked = $this.data("lastClicked") || 0,
      isScheduled = $this.is(".scheduled");

  if (!isScheduled) {
    $this.addClass("scheduled");
    setTimeout(function () {
      somefunction()
      $this.removeClass("scheduled").data("lastClicked", new Date());
    }, Math.max(0, 5000 - (new Date() - lastClicked)));
  }
});

See: http://jsfiddle.net/Tomalak/ZXfMQ/1/

like image 189
Tomalak Avatar answered Feb 20 '23 07:02

Tomalak


If you're ok with using underscore.js, then I recommend using its debounce function:

$('#division').on('click', _.debounce(someFunction, 5000, true));

Also, here's an excellent article about how debouncing works.

If you want to roll your own debouncing, it's as simple as this:

$('#division').on('click', (function(func, wait, immediate) {
    var timeout,
        result;
    return function() {
        var self,
            args,
            callNow;
        function later () {
            timeout = null;
            if (!immediate) result = func.apply(self, args);
        }
        self = this;
        args = arguments;
        callNow = immediate && !timeout;
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
        if (callNow) {
            result = func.apply(self, args);
        }
        return result;
    };
}(someFunction, 5000, true))));

...just kidding, that's just underscore's debounce function inline.

like image 43
zzzzBov Avatar answered Feb 20 '23 07:02

zzzzBov