8

Hello everyone i just picked up jQuery

So my question is i want to stop a key from repeating when you hold it down

Example: Edit (i want it to stop .. so 1 character per keypress/keydown)

keypress: a

HoldDown: aaaaaaaaaaaaaaaaaaaaaaaaaaaaa

My code is:

 <input type='text'>

var stop= false;
var time =null;
$(':text').keypress(function(e) {
if(stop === true){e.preventDefault();}
    if (time !== null) {
        lastkey = time;
    }
    time = new Date().getTime();
    var between = time - lastkey;
    if (between <= 70) {
        stop = true;
    }
});
$(':text').keyup(function(){stop = false;});

Am i going about this the wrong way?

iinsaneii
  • 101
  • 1
  • 6
  • 1
    Possible duplicate of [Prevent JavaScript keydown event from being handled multiple times while held down](http://stackoverflow.com/questions/6087959/prevent-javascript-keydown-event-from-being-handled-multiple-times-while-held-do) – Isti115 Jul 07 '16 at 08:55

3 Answers3

8

Use the .keyup() bind instead of .keypress().

Stout Joe
  • 324
  • 2
  • 4
  • 14
Elliot Bonneville
  • 51,872
  • 23
  • 96
  • 123
4

Try this: http://jsfiddle.net/maniator/yFA8c/

It will only allow a letter per every 2 seconds.

Code:

var mult = false,
    prev = 0;

$('.mult').keydown(function(e) {
    if (!mult) {
        mult = true;
        prev = e.which;
        setTimeout(function() {
            mult = false;
        }, 2000)
    }
    else if (prev != e.which) {
        mult = false;
    }
    else {
        return false;
    }
})​;​
Naftali
  • 144,921
  • 39
  • 244
  • 303
  • Why not use .keyup() instead? Of course, you would only type when you release, but I doubt the distinction is too important for most people typing at normal speeds. – Elliot Bonneville Mar 13 '12 at 19:58
  • instead prevent for "x" seconds, just disable the keydown event if the same key was pressed before, like I did – Rafael Verger Mar 13 '12 at 20:06
  • humm... but if I keep a key pressed for 10 seconds the key will be printed in text field 5 times... so, it will not do what @user1267070 wants – Rafael Verger Mar 13 '12 at 20:11
  • @RafaelVerger the OP wants it repeat within X amount of time. See the OP. – Naftali Mar 13 '12 at 20:12
  • He tried to block any key from be printed if it was printed 70 milliseconds before, and the question title says "Stop key from repeating on hold", so I think that he don't wanna to stop the repeat only by 'X' seconds... – Rafael Verger Mar 13 '12 at 20:16
  • @user1267070 what is wrong with the code posted in my answer? – Naftali Mar 13 '12 at 20:22
  • Its fine ... i was just thinking if you can stop the key from repeating when being depressed.. – iinsaneii Mar 13 '12 at 20:27
  • @Elliot Bonneville - the auto-repeat occurs on keydown & stops on keyup. I too prefer keyup but in this case (& several others) I think it has to be keydown. – Zeek2 Feb 22 '17 at 10:46
2

You should use keydown and keyup events instead keypress.

So, here is a solution:

window.keypressed = {};
$('#element').keydown(function(e){
  if ( window.keypressed[e.which] ) {
    e.preventDefault();
  } else {
    window.keypressed[e.which] = true;
}).keyup(function(e){
  window.keypressed[e.which] = false;
});
Rafael Verger
  • 1,751
  • 13
  • 18
  • @user1267070 check this code... it will prevent any key being printed more than one time in a text field – Rafael Verger Mar 13 '12 at 20:28
  • 1
    Well done, simple and clean. I used var charCode = (typeof e.which === "number") ? e.which : e.keyCode; then used charCode instead of e.which. – DeadlyChambers Oct 09 '14 at 20:14
  • Well done @DeadlyChambers , but when you use jQuery `e.which` is the keyboard code already processed (in a cross-browser way) – Rafael Verger Oct 11 '14 at 15:40
  • ok, so since it's not pure js this extra check and assignment is overkill. Thanks – DeadlyChambers Oct 14 '14 at 15:12
  • 1
    @DeadlyChambers yes.. the question was about jQuery use, so this check isn't necessary; But using a vanilla js solution it would be necessary to make the code work in all browsers – Rafael Verger Oct 14 '14 at 23:50