An important distinction is that it is easier to know if cntrl and z are pressed at the same time, but not as straight forward to detect if z and x are pressed at the same time. What is the best way to go about detecting when multiple characters are pressed at the same time?
This example uses event listeners to keep track of an object which contains all keys currently being pressed.
We can use this object to check if certain keys are pressed. This means that we can detect as many simultaneous key presses as a user's keyboard will allow.
Importantly it will let you detect when multiple characters are pressed at the same time.
const keysPressed = {};
document.addEventListener('keydown', (event) => {
if (!event.repeat)
keysPressed[event.key] = true;
//You can also include event.repeat as a condition in your cases if you wish an event to only occur once each trigger.
//You can also include Object.keys(keysPressed).length === 2 (for example) if you only wish the case to be valid if just two keys are pressed.
//Finally, instead of event.key === 'x' you can write keysPressed['x']. This would replace both non-default cases in the example. The result is that the event will continue firing if another key is pressed.
switch (true) { //You use true here because we are using logic to determine each case
case event.key === 'x' && keysPressed['z']:
case event.key === 'z' && keysPressed['x']:
console.log('Z and X pressed!');
break;
default:
break;
}
});
document.addEventListener('keyup', (event) => {
if (!event.repeat)
delete keysPressed[event.key];
});
I'm simply using an array as storage for all keys that are pressed. This array is cleaned to an empty state when keys are released.
In keydown event listener, you can hook the function with logic that you will want to implement. Read keys array to check all currently pressed keys.
const keys = []
document.addEventListener('keydown', e => {
!event.repeat && keys.push(e.key)
doSomethingWithKeys(keys)
})
document.addEventListener('keyup', e => {
keys.splice(0, keys.length)
})
function doSomethingWithKeys(keys) {
console.log('keys pressed:', keys.join('+'))
}
Related
I am doing an experiment and I want a part to be shown if a certain key ("b") is pressed and skipped, if any other key is pressed. The key that is pressed is saved in key_resp_3.keys and if I visualize what's saved in the key_resp_3.keys variable it's simply b.
So I thought this would be the right comparison:
if ((key_resp_3.keys != "b")) {
continueRoutine = false;
}
However in this case, the routine is always skipped so somehow "b" is obviously not the way the key is saved in the key_resp_3.keys variable. Does anyone have an idea what is the right comparison instead?
Thank you!
Hard to tell the root cause of the problem without the rest of the code. But you can simply use an event listener like below
document.addEventListener('keydown', function(event) {
console.log(event.key)
const key = event.key
if(key == "b")
alert("b presed")
});
Or can it be as simple as you are trying to set const key_resp_3 = event.key then checking in the if key_resp_3.keys so you are trying to access variable.key.key
In this special case:
since the keys is a array you can use
Does contains b
key_resp_3.keys.includes('b')
Does not contains b
!key_resp_3.keys.includes('b')
I am working on a project which shows the character code of each key that is pressed down inside a text box.
My problem is that when certain keys, namely: Shift, Backspace, Space are pressed down, their character codes appear like: 16, 8, 32.
I want these keys to retain their normal behavior when pressed. So that space causes a space in the text box, and backspace deletes the character, and so on...but the rest of the keys to continue outputting their character code.
How can I go about accomplishing this?
You can just check for the keys and handle accordingly. Here's a demo:
document.getElementById("test-textbox").addEventListener("keypress", function(event) {
var code = event.keyCode || event.which;
if(code === 16 || code === 8 || code === 32) //check if space, shift, or backspace
return; //if yes, allow
console.log(code); //if not, log value
event.preventDefault(); //prevent entry
});
<input type="text" id="test-textbox">
This will allow the shift, backspace, and space keys to be pressed, but all others will be logged.
I think this will work for you.
var elementID = document.getElementById('elementID');
elementID.onkeydown = function(event) {
var key = event.keyCode || event.charCode;
if( key == 32 || key == 8 )
event.preventDefault();
};
As long as you…
don’t call the preventDefault method on the event object, and
don’t return false from the event handler
…you should be fine.
In particular, the handler…
function showCharCode(event) {
// NOTE: Don’t call `event.preventDefault()` here.
document.querySelector('.char-code').textContent = event.charCode;
// NOTE: Don't return false here.
}
… will still propagate the event to the default textbox (or input, or contenteditable) element.
In the code below, instead of using on keydown, is there a way I can use on e.which === 13 where the keydown is? This was it wont have to check each time a key is pressed, and will work only when enter is pressed.
Current Code
$('.search').on('keydown', function(e) {
if(e.which === 13) {
// enter key pressed
var value = this.value; // this is the inputs value
console.log(value);
}
});
What I hope to do (pseudo code)
$('.search').(when key === 13 is pressed) { // Only if the enter key pressed
// enter key pressed
var value = this.value; // this is the inputs value
console.log(value);
}
});
Can something like this be done?
You could use a higher-order function to extract that logic for you:
function onlyOnEnter(fn) {
return function(e) {
if(e.which === 13) {
fn.apply(this, arguments);
}
}
}
Usage:
$('.search').on('keydown', onlyOnEnter(function(e) {
var value = this.value; // this is the inputs value
console.log(value);
})
);
That way, your callback function will only be called when the key pressed is an enter.
Not really.
The best you can do is capturing events (you are using on but it could be any other event capturing method). There are many different kind of events (mouse events, keyboard events, control specific events, etc.), you have to look at the event, since each event type will have different properties.
For key pressing, there are some events available for capturing such as keypress, keydown and keyup. You can't expect that one specific key will have an event on its own because you want so save one line of code.
No, this isn't really possible (at least not for the purposes of your code) nor does it make a lot of sense. The keydown event is fired whenever a key is pressed.
Whether you are manually checking to see if it's the enter key or whether the browser or jQuery is doing it internally isn't tremendously relevant - regardless the browser will need to check which key was pressed any time any key is pressed to test whether it was the enter key.
Essentially you're wasting your time. There isn't going to be any measurable performance optimization by trying to do this. No matter how you try to detect the enter key being pressed, it will be tested for every keydown or keypress event regardless of which key is pressed.
im creating a simple 2d game, and I want save the keydown keys into array, and execute them inisde a loop, so the user can hold a key and make it look like the chartater is moving non stop.
i got a setInterval function that act like a game Timer, and it just loop it self all the time. i added a listener and an array to hold the key.
I checked the keys inside the array and it look fine but, the functions moveRight and moveLeft are not working for some reson.
here is the code:
this.keysPressed = new Array();
InitGameLoop: function () {
var that = this;
setInterval(function () {
$(document).keydown(function (e) {
var key = e.which;
that.keysPressed.push(key);
for (var i = 0; i < that.keysPressed.length; i++) {
if (that.keysPressed[i] == 38) {
that.moveRight(worldWidth, 10);
}
else if (that.keysPressed[i] == 37) {
that.moveLeft(10);
}
log(that.keysPressed, that.yPos);
that.keysPressed.pop();
}
});
}, 60);
my questions are:
what am i doing worng?
is this a good idea? (if not, please feel free to recommend me about another :) )
(sorry for my english)
Registering an eventhandler inside setInterval is always wrong. In your case, every 60 milliseconds you are creating an additional listener, and when you press a key, all of your listeners will fire. Also there is absolutely no need to store them in an array. Just register the listener once, and it will fire each time a key is pressed. If more than one keys are pressed, the listener will fire for each key individually.
$(document).keydown(function (e) {
var key = e.which;
console.log(key);
// call your according functions here
switch (key){
case 37: // moving left
// do stuff
// set a flag to indicate that you are moving left
moveleft = true;
break;
case 39: // moving right
// do stuff
// set a flag to indicate that you are moving right
moveright = true;
break;
}
});
Since you are catching the keydown, you should set flags. This way you can track which keys are pressed currently. On keyup, you are resetting these flags again (need another eventhandler for that).
Instead of storing the pressed keys in an array, make each key code activate a related var in a 'movement' array. e.g. when left is pressed, movement['left']=1. Use keyup to set it back to 0.
Have your loop check the array for each possible movement, and trigger the related functions in corelance to the active movements at that given moment.
I am working on making a simple Javascript game and need to be able to check if certain keys are being pressed. I have tried binding to the onkeydown event, but the problem that I am having is twofold: first, it won't let me check to see if more than one key is being pressed at any time. And second, it pauses after holding the key down before it starts spamming the event.
In my code, I could either have an event, or a function that checks every millisecond to see if the key is being pressed. Seeing as this is a game, I would really have no problem with either.
You can use onkeydown and onkeyup together:
var pressed={};
element.onkeydown=function(e){
e = e || window.event;
pressed[e.keyCode] = true;
}
element.onkeyup=function(e){
e = e || window.event;
delete pressed[e.keyCode];
}
with this code you store every pressed key code in the pressed variable and then you delete it when the key is released. So when you need to know which keys are pressed you can loop with a for(..in..) through the pressed object.