Javascript Checking Keyboard State - javascript

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.

Related

How To Detect Two Characters (Keys) Pressed At The Same TIme

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('+'))
}

Handling multiple keys pressed at once in JavaScript

For context: this is a JavaScript app running in the Xbox One. All of this is happening through the Xbox's virtual keyboard. Keep in mind that since I have figured out how the events are being fired, this shouldn't matter anymore, just how to deal with the two events at once.
It's not really multiple keys, what is happening is when I turn on CAPS for my app, I am getting two events keys at once: shift and whatever key I am actually pressing. The problem this is causing is that shift seems to be overriding whatever I am trying to spell, and no key is displayed in my input boxes.
I currently have a global function which takes care of all special events in the app, and I would like to handle this issue from over there but am not sure how to go about this issue.
Here is what I currently have:
// this is the global function where I would like to solve the issue
onStartup(function () {
var $html = $('html')
$html.on('keydown', function (evt) {
if (evt.isDefaultPrevented()) return
console.warn('key being pressed:', evt.keyCode)
if (evt.keyCode === 16) { // Note: 16 is shift's keycode
// do something to prevent shift from overriding the actual key I want to press.
return
}
})
})
When I press a key without CAPS being turned on, say a, which has the keyCode of 65, we have the following output:
key being pressed: 65
If however I try to do a capital a (or A), this is what happens:
key being pressed: 16
key being pressed: 65
What can I do to stop the shift from preventing me from actually typing the capital keys?
I figured it out! All I had to do was when shift was fired, to call evt.stopImmediatePropagation().
So basically, for my code:
// ...
if (keycodeControls.is('shift', evt)) {
evt.stopImmediatePropagation()
}

Building A Timer in Javascript/jQuery

I'm currently working on a website which would work somewhat like this one:
http://www.keyhero.com/free-typing-test/
I'd like to build a timer which starts on the user's first key press, and ends when the user presses 'Enter'. When the timer ends, I'd want to get the resulting time and push it off to the backend (Django for me) where the WPM will be calculated. However, I have no idea how to get started on this, as I have little experience with jQuery and Javascript and haven't been able to find useful pages.
So my question is, how would I do this? I can post some of my Django files if a better picture of what I am asking is needed.
You manage the key events with .keypress() for know when the person click in the keyboard.
http://api.jquery.com/keypress/
And for key = "ENTER", you just need to validate if is equal to key 13
$('#id_tag').keypress(function (e) {
var key = e.which;
if(key == 13) // the enter key code
{
alert("Clicked on enter");
return false;
}
});
I see that post too, that are using keyup():
JQuery Event for user pressing enter in a textbox?
Well you're going to have to capture the keypress/keydown/keyup event in a jQuery event, then start a setInterval and have that function increment a counter variable of sorts. Then you just reference that variable whenever you want to see how many seconds have passed. A crude example would be:
window.secondsSinceTyped = 0;
$('#textbox').one('keypress', function (e) {
window.setInterval(function () {
window.secondsSinceTyped++;
}, 1000);
});
Then just reference the variable secondsSinceTyped whenever you want to check the time. Note that I used the jquery one binding which will only bind the event once so that every time you type it doesn't rebind the event.

jQuery: avoid checking if the key pressed is 'enter' everytime

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.

Determining if key is pressed down in Javascript

I'm writing a platform game for my university project using the canvas element and Javascript. I'm well on my way, but I'm stuck at how to see if a certain key is being pressed in my players update loop.
I was thinking like this:
if(d) {
// move player right
} else if(a) {
// move player left
} else if(w) {
// move player up
} else if(s) {
// move player down
}
That's psudocode, obviously. The only resources to key presses in Javascript that I can find are events, nothing to see if a key is being pressed at a certain point.
Can anyone shed some light on this?
Setup 4 boolean variables if key is up or down. On keydown set it to true, on keyup set it to false. Than you can do if(key_d == true) { // key d is pressed }
That's the best way to do it. Its not "hacky", add event listeners to handle key presses.
I don't think you can get around using keydown, keyup, or keypress for determining which keys are pressed. However, instead of running this code within one of those event handlers, you could set and unset some global flag within them. Then, when this code runs (I'm assuming it'll be on some kind of interval?), it could check for the flag.
You need an event listener.
//function foo, returns keypress
function foo(e){
var evt=(e)?e:(window.event)?window.event:null;
if(evt){
var key=(evt.charCode)?evt.charCode:
((evt.keyCode)?evt.keyCode:((evt.which)?evt.which:0));
return key;
}
//set event listener
//you could also attach this to your canvas, but that will require tricks
//to make the canvas focusable
document.addEventListener('keydown', foo);

Categories

Resources