简体   繁体   中英

Keys pressed at the same time

Can I know the number of keys pressed at the same time in Javascript?

If so, how can I have an array of their keyCode ?

You can listen for keydown and keyup events.

var keys = { length: 0 };

document.onkeydown = function(e){
    if(!keys[e.keyCode])   {
        keys[e.keyCode] = true;
        keys.length++;
    }
}

document.onkeyup = function(e){
    if(keys[e.keyCode])   {
        keys[e.keyCode] = false;
        keys.length--;
    }
}

Then all the keys that are true are the ones that are pressed currently.

Fiddle demo thanks to @Esailija: http://jsfiddle.net/maniator/Gc54D/

This should do the trick. It is similar to Neal's, but should fix a few issues, including the leaving-the-window bug and the negative-numbers-of-keys bug. I also streamlined the message writing code a bit. I replaced the timer loop for writing the number of keys message with an on-demand system, added a safety mechanism for decrementing the length index, and added the clearKeys to switch all keys to up when the user leaves the window. The code still has two bugs: it will not recognize keys that are still held down after a new window has been opened and closed (they must be released and re-pushed), and I can't get it to recognize more then six keys (I suspect this isn't related to this code, but the computer/browser...).

var keys = {
    length: 0
};

window.onkeydown = function(e) {
    if (!keys[e.keyCode]) {
        keys[e.keyCode] = true;
        keys.length++;
        document.body.innerHTML = "You are pressing " + keys.length + " keys at the same time.";
    }
}

window.onkeyup = function(e) {
    if (keys[e.keyCode]) {
        keys[e.keyCode] = false;
        if (keys.length) {
            keys.length--;
        }
        document.body.innerHTML = "You are pressing " + keys.length + " keys at the same time.";
    }
}

function clearKeys() {
    for (n in keys) {
        n = false
    };
    keys.length = 0;
    document.body.innerHTML = "You are pressing " + 0 + " keys at the same time.";
}

document.body.innerHTML = "You are pressing 0 keys at the same time.";
window.onblur = clearKeys;

Since you want the number of keys pressed at the same time and an array of their key codes I suggest you use the following function:

var getKeys = function () {
    var keys = [];

    window.addEventListener("blur", blur, false);
    window.addEventListener("keyup", keyup, false);
    window.addEventListener("keydown", keydown, false);

    return function () {
        return keys.slice(0);
    };

    function blur() {
        keys.length = 0;
    }

    function keyup(event) {
        var index = keys.indexOf(event.keyCode);
        if (index >= 0) keys.splice(index, 1);
    }

    function keydown(event) {
        var keyCode = event.keyCode;
        if (keys.indexOf(keyCode) < 0)
        keys.push(keyCode);
    }
}();

When you call getKeys it will return an array of all the keys pressed at the same time. You can use the length property of that array to find the number of keys pressed at the same time. Since it uses addEventListener it works cooperatively with other code on the page as well.

I tested the above function and it always returns the correct keys pressed even when you switch to another window while holding down a key (it removes that key from the array). If you hold a key and switch back then it recognizes that a key is pressed and it pushes in onto the array. Hence I can testify that there are no bugs in the above code. At least not on the browser I tested it on (Opera 12.00).

I was able to press 8 keys at the same time ( A , S , D , F , J , K , L and ; ). This number seems OS specific as I can only press 4 left hand keys and 4 right hand keys at the same time. For example after I press A , S , D and F , and then I press another left hand (let's say G ) then it won't recognize the last key. This is probably because the OS knows how humans type and so it only allows four interrupts for each of the left and right hand keys. The OS I am using is Ubuntu 12.04.

You can see the code in action on this fiddle . I used a Delta Timer instead of setInterval to display the results after every 50 ms. You may also wish to read the following answer as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM