简体   繁体   中英

How to detect if multiple keys are being pressed at the same time in html using JavaScript

I am currently working on a keyboard recognition project and creating a simple game in order to demonstrate my understanding of it. When I press the four keys: W, S, A, D, it will print out the direction corresponding to them. (ex. W = Up). A demo down below:

 var msg = new SpeechSynthesisUtterance(); var synth = window.speechSynthesis; function uniKeyCode(event) { var key = event.which || event.keyCode; // console.log(key) if (key == 32 || key == 13) { document.getElementById("actionCenter").innerHTML = "fire" msg = new SpeechSynthesisUtterance("fire"); //settings msg.rate = 1.2; //speech speed - range: 0 to 10 //look into console to see all available voices/languages msg.voice = synth.getVoices()[0]; //speaking trigger synth.cancel(); //cut previous voice short synth.speak(msg); } if (key == 87 || key == 38) { document.getElementById("actionCenter").innerHTML = "jump" msg = new SpeechSynthesisUtterance("jump"); msg.rate = 1.2; msg.voice = synth.getVoices()[0]; synth.cancel(); synth.speak(msg); } if (key == 83 || key == 40) { document.getElementById("actionCenter").innerHTML = "roll" msg = new SpeechSynthesisUtterance("roll"); msg.rate = 1.2; msg.voice = synth.getVoices()[0]; synth.cancel(); synth.speak(msg); } if (key == 65 || key == 37) { document.getElementById("actionCenter").innerHTML = "roll left" msg = new SpeechSynthesisUtterance("roll left"); msg.rate = 1.2; msg.voice = synth.getVoices()[0]; synth.cancel(); synth.speak(msg); } if (key == 68 || key == 39) { document.getElementById("actionCenter").innerHTML = "roll right" msg = new SpeechSynthesisUtterance("roll right"); msg.rate = 1.2; msg.voice = synth.getVoices()[0]; synth.cancel(); synth.speak(msg); } }
 .center { text-align: center; }
 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="style.css"> <title>Assignment 11a2</title> </head> <body onkeydown="uniKeyCode(event)"> <p class="center">Actions <br> <span id="actionCenter"></span></p> <script src="11a2.js"></script> </body> </html>

Right now I am trying to make an action for when multiple keys are pressed at the same time(ex. W + A = Jump Left). I tried this:

if (key == 87 && key == 65) {
   document.getElementById ("actionCenter").innerHTML = "Jump Left"
}

but apparently, it did not work. The code runs as if those three lines do not exist. What is the problem?

No value can be both 87 and 65 at the same time; this is the reason your if will never trigger. If you press two keys "simultaneously", it will still fire two separate keydown events.

In order to detect 87 and 65 being pressed at the same time, you can do two different approaches:

  • Track last time each key was pressed. If eg 87 was pressed, and 65 was pressed a short time ago, trigger your code.

  • On keydown , note that the key is down. On keyup , note that the key is up. React when both 87 and 65 are down.

For each key pressed, a new event will fire up and call your listener function.

To check, if at the time, there are multiple keys pressed, you could store the key value in a global array and compare.

So, for every keydown event you have to push the key value in a global array and for every keyup event remove that key value from the array.

The easiest way is use JQuery's keypress event and pass the value to a switch in order to know the multiple keys pressed:

    $(document).keypress(function(evt){
        var x = evt.which || evt.keyCode; 
        console.log(x);
    switch(evt.keyCode){
        case 119:
            //alert("Key press  \"W\"");
            //Go to North coordinates
        break;
        case 115:
            //alert("Key press \"S\"");
            //Go to South soordinates
        break;                
        case 97:
            //alert("Go to \"East\"");
        break;           
        case 100:
            //alert("Se presionó la flecha \"West\"");
            // ... 
        break; 
        case 113:
            ...
        break;
        case 101:
            ...
        break;       
        case 122:
            ...
        break;
        case 99:
            ...
        break;                
        case 13:
            ...
        break;}

You can set any key you want with their ascii code

Or if you want only JS try:

document.getElementById("container").addEventListener("keypress", myFunction);

function myFunction(evt) {
    var x = evt.which || evt.keyCode; 
    console.log(x);
    //Switch here
    //...
}

Maybe you need some flags in order to know wich key has pressed (or not).

Here's an implementation of Bradens answer.

 var keys = {} function handleKeyPress(evt) { let { keyCode, type } = evt || Event; // to deal with IE let isKeyDown = (type == 'keydown'); keys[keyCode] = isKeyDown; // test: enter & shift key pressed down if(isKeyDown && keys[13] && keys[16]){ console.log('enter + shift pressed') } }; window.addEventListener("keyup", handleKeyPress); window.addEventListener("keydown", handleKeyPress);

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