views:

1139

answers:

4

Is there a way to detect if a key is currently down in JavaScript?

I know about the "keydown" event, but that's not what I need. Some time AFTER the key is pressed, I want to be able to detect if it is still pressed down.

P. S. The biggest issue seems to be that after some period of time the key begins to repeat, firing off keydown and keyup events like a fiend. Hopefully there is just a simple isKeyDown(key) function, but if not then this issue will need to be overcome / worked around.

+1  A: 

Look at this answer, and use onkeyup and onkeydown. Here is more specific info about those events.

Claudiu
The link you cite is for the mouse events, where auto-repeat is not a problem.
Carl Smotricz
key-up and key-down won't repeat. key-press might.
Claudiu
well even if they do, I was imagining something like TJMonk15's solution, just didn't want to write it up
Claudiu
The wording on those two questions is exactly the same. Weird coincidence, or something more?
Mitch Lindgren
@Mitch: wow... that's pretty incredible. i don't know why someone would make two accounts to ask the same question. or more likely this person just copied the other question and adapted it for keys
Claudiu
+1  A: 

Other people have asked this kind of question before (though I don't see any obvious dupes here right now).

I think the answer is that the keydown event (and its twin keyup) are all the info you get. Repeating is wired pretty firmly into the operating system, and an application program doesn't get much of an opportunity to query the BIOS for the actual state of the key.

What you can do, and perhaps have to if you need to get this working, is to programmatically de-bounce the key. Essentially, you can evaluate keydown and keyup yourself but ignore a keyupevent if it takes place too quickly after the last keydown... or essentially, you should delay your response to keyup long enough to be sure there's not another keydown event following with something like 0.25 seconds of the keyup.

This would involve using a timer activity, and recording the millisecond times for previous events. I can't say it's a very appealing solution, but...

Carl Smotricz
I was worried that it might come to this.
Daniel X Moore
+3  A: 

I don't believe there is anything like an isKeyDown function, but you could right your own.

Basically, create an array thats length is the number of keys you want to monitor. Then using the documents/pages/controls keyUp and keyDown events, update the array with that keys state.

Then write a function that checks if a certain key is down and returns a bool.

var keyEnum = { W_Key:0, A_Key:1, S_Key:2, D_Key:3 };
var keyArray = new Array(4);

function onKeyDown()
{
    // Detect which key was pressed
    if( key == 'w' )
        keyArray[keyEnum.W_Key] = true;
    // Repeat for each key you care about...
}

function onKeyUp()
{
    // Detect which key was released
    if( key == 'w' )
        keyArray[keyEnum.W_Key] = false;
    // Repeat for each key you care about...
}

function isKeyDown(key)
{
    return keyArray[key];
}

That should accomplish what you want.

TJMonk15
This is good, and indeed part of the solution, but it doesn't address the keyup repeating bug I am experiencing. See bobince's answer.
Daniel X Moore
+2  A: 

Is there a way to detect if a key is currently down in JavaScript?

Nope. The only possibility is monitoring each keyup and keydown and remembering.

after some period of time the key begins to repeat, firing off keydown and keyup events like a fiend.

It shouldn't. You'll definitely get keypress repeating, and in many browsers you'll also get repeated keydown, but if keyup repeats, it's a bug.

Unfortunately it is not a completely unheard-of bug: on Linux, Chromium, and Firefox (when it is being run under GTK+, which it is in popular distros such as Ubuntu) both generate repeating keyup-keypress-keydown sequences for held keys, which are impossible to distinguish from someone hammering the key really fast.

bobince
You sir are a gentleman and a scholar. Chromium and Firefox on Ubuntu are my primary development environment, so that accurately explains the issue I've been seeing. Hopefully it will get better, otherwise that timer hack solution might be the only workaround.
Daniel X Moore
Yeah, it is frustrating that there is no progress on this. See https://bugs.launchpad.net/ubuntu/+bug/369880 . I'm writing a browser game and my workaround for the moment is to stick to the modifier keys (shift, ctrl, etc.) which do not repeat at all.
bobince