开发者

Differentiate between key pressed and key held

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 ab开发者_运维知识库out 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


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
  }
});


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


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.


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;
  }
});


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?


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
});


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜