Differentiate between key pressed and key held
Asked Answered
S

7

11

I have a javascript function which runs when the 'down' key is pressed. I would like, that if the 'down' key is held down, the function would not run at all.

I thought about timing between keydown and keyup, if the time is less than 1 second then the function would run on keyup. The problem is, if I hold the key down the browser sees it as the key being pressed many times in succession.

Is there a better way to do this?

Thanks

Spiritualty answered 23/8, 2011 at 17:1 Comment(2)
What's the context? If you're in a textbox, would it make sense to track the value of the input before the last key press, then check to see if multiple characters were added on the next key up event? Just fishing around...Geniegenii
Could you set a flag (e.g. a boolean variable) when the first keydown event fires (but not if it's already set), and unset it when keyup fires?Meghanmeghann
P
1

If I understand your problem is that your browser interprets a key being held as multiple keydown events. You want something different to happen if a key is held versus when it's simply pressed; and you want that difference to be based on some time which you think should constitute "holding" the key. So you need to differentiate between a hold and a press by tracking the keyup event. The following pseudocode will resolve this problem:

On Keydown:

if !yourBool 
    start timer

yourBool = true 

on Keyup:

if timer < yourTime
    do something

yourBool = false

This will work because the timer will not restart unless keyup event has occurred.

Now... if your browser interprets key holding as:
Keydown, Keyup, Keydown, Keyup.......
then you have a problem with this approach.

Perpetua answered 23/8, 2011 at 17:9 Comment(0)
V
18

There is a keyboard event property called repeat that returns true if the key is being held down.

document.addEventListener('keydown', (event) => {
  if(event.repeat) {
    // key is being held down
  } else {
    // key is being pressed
  }
});
Vetter answered 19/7, 2018 at 20:24 Comment(0)
R
3

I just wrote this little script that differentiates between a key pressed and a key eld down for 200 milliseconds. Perhaps you can make use it:

document.onkeydown = function(e){
    var keycode = window.event ? window.event.keyCode : e.which;
    if(keycode == 40){
        var timer = setTimeout(function(){
            alert('Down key held');
            document.onkeyup = function(){};
        }, 200); 
        document.onkeyup = function(){
            clearTimeout(timer);
            alert('Down key pressed');   
        }
    }
};

JSFiddle

Reproachful answered 23/8, 2011 at 17:11 Comment(0)
P
1

If I understand your problem is that your browser interprets a key being held as multiple keydown events. You want something different to happen if a key is held versus when it's simply pressed; and you want that difference to be based on some time which you think should constitute "holding" the key. So you need to differentiate between a hold and a press by tracking the keyup event. The following pseudocode will resolve this problem:

On Keydown:

if !yourBool 
    start timer

yourBool = true 

on Keyup:

if timer < yourTime
    do something

yourBool = false

This will work because the timer will not restart unless keyup event has occurred.

Now... if your browser interprets key holding as:
Keydown, Keyup, Keydown, Keyup.......
then you have a problem with this approach.

Perpetua answered 23/8, 2011 at 17:9 Comment(0)
C
1

I had a similar problem. I wanted to capture all "first" keydown events, but ignore successive events if they were the result of a key being held down. Not sure if that's what you want, but here's one approach:

var repeat = false;
el.addEventListener("keyup", function() { repeat = false; });
el.addEventListener("keydown", function() {
  if (!repeat) {
    // Run your code.
    repeat = true;
  }
});
Crinkle answered 18/9, 2016 at 2:3 Comment(0)
B
0

Perhaps you could trigger a counter on keydown and then listen for the next keyup. As soon as the counter goes over five seconds, or however much time you deem, you could start the function. Make sense?

Baruch answered 23/8, 2011 at 17:6 Comment(0)
O
0

Successive keydowns will not fire a keyup, so it is possible to differentiate between them.

http://jsfiddle.net/pimvdb/xMFGQ/

$('body').keydown(function() {
    if(!$(this).data('timeDown')) { // if not pressed yet, save time
        $(this).data('timeDown', +new Date);
    }
}).keyup(function() {
    var diff = new Date - $(this).data('timeDown'); // time difference
    if(diff < 1000) { // less than one second
        alert(123);
    }
    $(this).data('timeDown', null); // reset time
});
Orta answered 23/8, 2011 at 17:9 Comment(0)
N
0

The browser sees the key being pressed many times but the keydownevent only happens on the first press.

What you want is to time it from the keydown event and not keypressed.

Nestling answered 23/8, 2011 at 17:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.