0

I am using the .one() function on a keydown to stop the function inside this running continuously if the the user holds down the key.

The problem is, the .one() function only runs once, and will only work again when I refresh the page.

$(document).one('keydown',function(e){
    if (e.keyCode == 37) { 
        prev();
        return false;
    }
});

Is there a way to get around this, or an alternative method?

I get that .one() means once, and that this is the point of the function. I am trying to get it to run just once per keydown.

ccdavies
  • 1,576
  • 5
  • 19
  • 29
  • 4
    `one()` is named like this exactly because it fires up only once. Have you tried `on()` ? – Ski Oct 30 '14 at 13:09
  • I get that, but wanted it to run once per 'keydown'. .on() runs the function multiple times if the key is held down. – ccdavies Oct 30 '14 at 13:10
  • possible duplicate of [How to disable repetitive keydown in jQuery](http://stackoverflow.com/questions/9098901/how-to-disable-repetitive-keydown-in-jquery) – PeterKA Oct 30 '14 at 13:28

3 Answers3

1

Simple hack:

var pressed = false;
$(document).on('keydown',function(e){
    if (e.keyCode == 37 && !pressed) { 
        pressed = true;
        prev();
        return false;
    }
});

Then you just want to make sure that your set pressed = false; again if you want to call the prev() function again (maybe at the end of the pev() function ...). This could alsp happen onkeyup:

$(document).on('keyup',function(e){
    pressed = false;
});

It really depends on your needs.

SmartDev
  • 2,802
  • 1
  • 17
  • 22
1

You could use the timeStamp property of event and compare with the previous value and return false if the time difference is too short -- repeated key. However, you do need to use .on():

var t = Date.now();
$(document).on('keydown',function(e){
    if( e.timeStamp - t < 100 ) {
      t = e.timeStamp;
      $('pre.out').append( (e.timeStamp - t) + ': Bad\n' );
      return false;
    }
    t = e.timeStamp;
    if (e.keyCode == 37) { 
        $('pre.out').append( 'Bad\n' );
        return false;
    }
    $('pre.out').append( 'Good\n' );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" name="test" />
<pre class="out"></pre>

UPDATE:

Please take a look at similar questions:

  1. How to disable repetitive keydown in jQuery
  2. jQuery keypress event fires repeatedly when key is held - but not on all keys
  3. Stop key from repeating on hold. (jQuery)
Community
  • 1
  • 1
PeterKA
  • 24,158
  • 5
  • 26
  • 48
1

One does just what you want it to, it runs once! This is actually a very good way to prevent people from double submitting forms etc, but needs a slightly different design. I've found it's easiest to use a named function here myself, try this

function handle_key_down_event (e) {
    if (e.keyCode == 37) { 
        prev();
        return false;
    }
    document.one('keydown',handle_key_down_event (e));
}
document.one('keydown',handle_key_down_event (e));

by restating the declaration at the end of the function, you reset it again. A small trick to keep in mind is if you're doing asynch (primarily ajax) operations, you may want the re-binding call to be at the end of a callback instead of the function.

Edit: After reading your comments, probably the best place to put a rebinding call would be in the keyup listener.

Sidney
  • 624
  • 7
  • 20