-2

I want to delay action of .keypress() method in jQuery for a certain amount of seconds.

I looked for the solution like:

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}

and setInterval,setTimeout methods as well but in the first variant it freezes the entiry page what I really don't want to do. and in the second I don't know how to wrap my script into these functions.

My code sample :

$(document).ready(function() {
//some code
    $(document).keypress(function(event){/*...this fragment I want to be freezed*/});
});

Question explanation:

Let's say that I have a simple counter which is in keypress event handler counts how many times Enter button is pressed by user. And after the third click I want page not to response on user presses for 5 seconds without freezing the whole page(user still can click on a certain <button> etc.. but any pressing on keyboard will do nothing untill 5 secs left(freeze keypress event handler).

Vadym
  • 548
  • 2
  • 8
  • 21
  • Your first code snippet is a busy loop -- it will peg one core to 100% while it's waiting for the delay to elapse. You should never do that. Look around for event *throttling* for answers to your main question. – Frédéric Hamidi Sep 27 '15 at 19:49
  • Im not sure if this will work, but try this: `$(document).delay(5000).keypress(function(){};);` – Manu Masson Sep 27 '15 at 19:50
  • 1
    @Manu It won't work. – JJJ Sep 27 '15 at 19:51
  • @Juhana setInterval doesn't work in my case... Unexplained downvoting. – Vadym Sep 27 '15 at 19:51
  • I can't think of a reason why setTimeout wouldn't work (you don't want setInterval because, well, you don't want an interval.) – JJJ Sep 27 '15 at 19:52
  • @FrédéricHamidi I know about busy loop and its dangerous. That's why I'm asking about another way to freez. – Vadym Sep 27 '15 at 19:52
  • @Juhana I didn't mention that I don't want it. Just suggest your way of using it instead of downvoting. – Vadym Sep 27 '15 at 19:53
  • 1
    And you don't want it because...? (I didn't downvote.) – JJJ Sep 27 '15 at 19:54
  • I want to use `setInterval` or `setTimeout` in any possible way but I can't figure out how to use it. That's why I'm asking here. Please read my question explanation above. – Vadym Sep 27 '15 at 19:55
  • @Vad, *why* would you want to use `setInterval()` or `setTimeout()` *without being able to figure out how to use [them]*? Have you read the documentation about timeout ids and how you revoke them? – Frédéric Hamidi Sep 27 '15 at 19:59
  • @FrédéricHamidi I wrote code. I tried to do it myself. I googled for good answers and practices and read documentation. After all I've come here for explanation from experts. – Vadym Sep 27 '15 at 20:03

2 Answers2

2

Here's something rather simple

var delay = ( function () {
    var ticker = null;

    return function( callback, ms ) {
        if ( ticker !== null ) {
            clearTimeout( ticker )
        }

        ticker = setTimeout(callback, ms)
    }
} () )

$(document).ready(function() {
    // Pass delay two parameters, the first one is the callback
    // You want to delay, the second is the time in milliseconds to wait
    $(document).on( "click", function() {
         delay( function(){ ... }, 3000 )
    } );
});

Here's an example of how to use this: http://jsfiddle.net/p0tf8of0/8/

Here is another variation of the delay function, this one accepts a third parameter used for delaying after a certain amount of invocations.

var delay = ( function () {
    var ticker = null;
    var invokedCounter = 0

    return function( callback, ms, delayAfter ) {
        if ( typeof delayAfter === "number" && delayAfter > 0 && delayAfter === invokedCounter ) {
            if ( ticker !== null ) {
                clearTimeout( ticker )
            }

            ticker = setTimeout(callback, ms)
        } else {
            invokedCounter++
            callback()
        }
    }
} () )

example: http://jsfiddle.net/p0tf8of0/12/

elad.chen
  • 2,375
  • 5
  • 25
  • 37
-1

Use debounce() function from lodash or underscore (a utility js library)

Debounce allow to trigger event only one time in the period defined.

jQuery('#myDiv').on('click', _.debounce(myFunction, 300, { 'leading': true, 'trailing': false }));

Julien Roy
  • 309
  • 3
  • 11