I'm working on a framework for making games and i have a function for taking key input.
But since its a framework specific options need to be optional an example would be if you want movement by arrow keys, 'aswd' or maybe even mouse but if you want to use mouse you don't want to have arrow keys activated
so what i need to do is add if statements to the function after its declared.
The function:
Note: there is nothing wrong with the function it works fine
var key = [];
onkeydown = onkeyup = function(e){
e = e || even;
key[e.keyCode] = e.type == 'keydown';
//insert here
};
Is there i can add this:
to the place where it says //insert here
if(map[17] && map[16] && map[65]){ // CTRL+SHIFT+A
alert('Control Shift A');
}
Help would be much appreciated.
Related
I have 2 click event listeners one is for toggle and second for remove class. Now, I don't want to repeat my code over and over again but instead, I would like to have a clean & dry approach to the same goal.
As you can see i have some classes but the only actual difference is toggle and remove.
Is there a cleaner way of doing such a thing?
My JS:
const onNavOpen = e => {
e.preventDefault();
body.classList.toggle('nav-body-is-open');
body.classList.toggle('bg-overlay');
navigationHamburger.classList.toggle('active');
navigationMenu.classList.toggle('nav--open');
};
const onNavClose = e => {
e.preventDefault();
if (
body.classList.contains('nav-body-is-open') &&
e.keyCode === 27
) {
body.classList.remove('nav-body-is-open');
body.classList.remove('bg-overlay');
navigationHamburger.classList.remove('active');
navigationMenu.classList.remove('nav--open');
}
};
Create a function object that points to either remove or toggle function based on condition.
Something like below. (Note - I haven't tested the code)
const resolvedFunction = body.classList.contains('nav-body-is-open') && e.keyCode === 27 ? body.classList.remove : body.classList.toggle;
resolvedFunction('nav-body-is-open');
resolvedFunction('bg-overlay');
resolvedFunction('active');
resolvedFunction('nav--open');
I'm writing a script for the following task:
The task is for participants to alternately press the a and b keys on the keyboard as quickly as possible for 10 minutes. Every time a participant successfully press the a key followed by the b key, they should receive a point. Points should only be awarded for alternating key presses, pressing the a key or the b key without alternating between the two should not result in points.
The part of the problem I am asking about is the detection of alternating key events. I attempted this myself and ended up with the code below, but it does not achieve the desired result and I'm getting the following error:
Uncaught ReferenceError: x is not defined
... but I just don't understand what I'm doing wrong.
How can I fix my code and achieve the desired result?
var points = 0;
document.addEventListener('keydown', function(event) {
var x = event.code;
});
document.addEventListener('keydown', function(event) {
if (x == 'KeyA' && event.code == 'KeyB') {
points = points + 1;
document.getElementById("points").innerHTML = points;
}
});
<p>Points: <span id="points">0</span></p>
You only need one event listener, and you need to define the a key press state variable (x) outside of the listener function so that it can be referenced by subsequent executions of the listener function.
You also need to make sure that you reset the a key press variable after the b key press.
it is also generally a good idea to cache your references to elements, rather than selecting the element from the DOM each time your listener function runs, and using textContent instead of innerHTML bypasses the HTML parser.
const target = document.getElementById('points');
var points = 0, x;
document.addEventListener('keydown', function(event) {
if(event.key === 'a') x = true; // If this is an `a` key event, set x to true
if(event.key === 'b') {
// if this is a `b` key event and a was not pressed, return early
if(!x) return;
// otherwise increment the points variable and assign the result to
// the textContent property of the target element
target.textContent = ++points;
// remember to set x to false again
x = false;
}
});
<p>Points: <span id="points">0</span></p>
I am trying to create a look up table ( as i have large number of keys to handle) for handling my keys functionality. So far i have been able to handle single key presses as shown below:
(function(){
document.body.addEventListener('keydown',keysHandler,false);
var keyLookUp = {37:leftKey,39:rightKey,40:DownKey...etc}
function keysHandler(e){
event = e || window.event;
var keycode = event.which || event.keyCode;
keyLookUp[keycode](e);
}
function leftKey(e){
}
function rightKey(e){
}
function DownKey(e){
}
})();
How can i modify the above code to handle the multiple key press functionality also?? like pressing Shift + left key
How can i modify the above code to handle the multiple key press [such as] pressing Shift + ←
The keys Shift, Ctrl, Alt and Alt Gr are modifier keys, this means that they're sent as part of the event you call e and are stored as e.shiftKey, e.ctrlKey, e.altKey and e.altGraphKey, respectively.
So what does this mean for you? If you want to keep your current structure, I see you as having three choices; you can
write completely different functions for the modified versions, e.g.
keyLookUp['37sc'] = leftKeyShiftCtrl;
keyLookUp[
keycode
+ (e.shiftKey ? 's' : '')
+ (e.ctrlKey? 'c' : '')
+ (e.altKey ? 'a' : '')
](e);
look at these values in you current handlers
// inside fn
if (e.shiftKey) {/* different code path */}
pass these as parameters into your handlers (which take extra args)
function leftKey(e, shift, ctrl, alt) { /* ... */ }
keyLookUp[keycode](e, e.shiftKey, e.ctrlKey, e.altKey);
For any combination of keys, you need to track keydown and keyup, see this question
Is it possible to know, what 2 last keys was pressed on keyboard?
How can I do it?
I need to compare this keys, and if they are the same - make some function.
As example, if someone press Enter - this is a first function, if after Enter he press a SPACE- this is a second function. If after the ENTER he press a Ctrl - this is a third function.
So, I hink that only onw way to do it - is make a 2 var with current and previous key value, and make a IF ELSE IF function
:-)
This is a way, how I get a current key value
$('#text').keydown(function(event) {
$('#show').text(event.keyCode);
});
Or, the BETTER question! (I saw it right now)
Directly in this editor, after I press doublespace - it jump to anothe line in live-preview.
How it works? I'm not sure, but I thinks that I need is almost the same.
Thank you very much!
I think storing the last key pressed and checking both the old and new keyCode in the event handler is a good way to do this.
$('#text').keydown((function() {
var lastKey = undefined;
return function(event) {
// here you have both the old and new keyCode
lastKey = event.keyCode;
};
})());
Also, the two spaces thing is Markdown interpretation.
You could start with a very simple jQuery plugin:
(function($) {
$.fn.keyWatcher = function() {
return this.keydown(function(evt){
var $this = $(this);
var prevEvt = $this.data('prevEvt');
$this.trigger('multikeydown',[prevEvt,evt]);
$this.data('prevEvt',evt);
});
};
})(jQuery);
This will raise a new event (multikeydown) whenever a keydown event is usually raised. This will either provide just the keydown event from the current key press, or if there is a previous one it will provide that too.
Usage could be something like:
$(document).keyWatcher().bind('multikeydown',function(evt,prevKey,currKey){
alert('prevKey = ' + ((prevKey) ? String.fromCharCode(prevKey.keyCode) : '(none)'));
alert('currKey = ' + String.fromCharCode(currKey.keyCode));
});
Live example (press keys on the lower right hand pane in jsfiddle): http://jsfiddle.net/9VMUy/1/
The event provided in prevKey and currKey parameters to the event handler contain the original keydown events, so you have full access to the keyCode, the ctrlKey and shiftKey properties etc.
This is probably not the best solution but see if you can use it or parts of it
jsFiddle
var clicks = 0
$("#text").one("keypress", function () {
clicks = 1;
var KeyCode1 = event.keyCode;
$('#result').text(KeyCode1);
$("#text").one("keypress", function () {
clicks = 2;
var KeyCode2 = event.keyCode;
$('#result').text(KeyCode1 + "\n" + KeyCode2);
});
});
I'm curious how i, with the following jQuery plugin code im writing at the bottom of this question, could implement key combos. How it's working so far is it allows a user to create key commands simply by doing a normal jQuery like syntax and provide an event for the key command, like so:
$(window).jkey('a',function(){
alert('you pressed the a key!');
});
or
$(window).jkey('b c d',function(){
alert('you pressed either the b, c, or d key!');
});
and lastly what i want is the ability to do, but can't figure out:
$(window).jkey('alt+n',function(){
alert('you pressed alt+n!');
});
I know how to do this outside of the plugin (on keyup set a var false and on keydown set the var true and check if the var is true when you press the other key), but i don't know how to do this when you dont know what keys are going to be pressed and how many. How do I add this support? I want to be able to allow them to do things like alt+shift+a or a+s+d+f if they wanted. I just can't get my head around how to implement this. Any ideas?
I'm going to release this as an open source plugin and i'd love to give whoever gives me the right, working, answer some credit on the blog post and in the code it's self. Thanks in advance!
(function($) {
$.fn.jkey = function(keyCombo,callback) {
if(keyCombo.indexOf(' ') > -1){ //If multiple keys are selected
var keySplit = keyCombo.split(' ');
}
else{ //Else just store this single key
var keySplit = [keyCombo];
}
for(x in keySplit){ //For each key in the array...
if(keySplit[x].indexOf('+') > -1){
//Key selection by user is a key combo... what now?
}
else{
//Otherwise, it's just a normal, single key command
}
switch(keySplit[x]){
case 'a':
keySplit[x] = 65;
break;
case 'b':
keySplit[x] = 66;
break;
case 'c':
keySplit[x] = 67;
break;
//And so on for all the rest of the keys
}
}
return this.each(function() {
$this = $(this);
$this.keydown(function(e){
if($.inArray(e.keyCode, keySplit) > -1){ //If the key the user pressed is matched with any key the developer set a key code with...
if(typeof callback == 'function'){ //and they provided a callback function
callback(); //trigger call back and...
e.preventDefault(); //cancel the normal
}
}
});
});
}
})(jQuery);
Use keypress instead of keyup/keydown because the latter two do not accurately protray the keycode (reference, see last paragraph). You can reference the altKey ctrlKey and shiftKey boolean properties of the event object in this case...
$(document).keypress(function(e) {
var key = String.fromCharCode(e.which);
var alt = e.altKey;
var ctrl = e.ctrlKey
var shift = e.shiftKey;
alert("Key:" + key + "\nAlt:" + alt + "\nCtrl:" + ctrl + "\nShift:" + shift);
});
Also, you can use String.fromCharCode to translate the key code to an actual letter.
You can't trap multiple keys aside from combinations with Ctrl, Alt, and Shift. You simply can't do it in a single event. So throw the a+s+d+f idea out the window.
Note: Obviously there are certain key combinations that are used by the browser. For instance, Alt + F usually brings up the File menu in Windows. Ctrl + N usually launches a new window/tab. Do not attempt to override any of these combinations.
Here's a live demo for your testing pleasure.
Here's what I came up with. Essentially what I did was created a JSON object that stores all the key codes. I then replace all the provided keys with the codes. If the keys are using the '+' to make a key combo, I then create an array of the codes out of it.
We then create another array that stores all the keys that are being pressed (keyDown add the item, keyUp removes it). On keyDown, we check if it's a single key command or combo. If it's a combo, we check it against all the currently active key presses. If they all match, we execute the callback.
This will work with any number of key combos. Only time I saw that it wasn't working is when you use the 'alert()' to display a message on the key combo because it will no longer remove the items from the active key press array.
(function($) {
$.fn.jkey = function(keyCombo,callback) {
// Save the key codes to JSON object
var keyCodes = {
'a' : 65,
'b' : 66,
'c' : 67,
'alt' : 18
};
var x = '';
var y = '';
if(keyCombo.indexOf(' ') > -1){ //If multiple keys are selected
var keySplit = keyCombo.split(' ');
}
else{ //Else just store this single key
var keySplit = [keyCombo];
}
for(x in keySplit){ //For each key in the array...
if(keySplit[x].indexOf('+') > -1){
//Key selection by user is a key combo
// Create a combo array and split the key combo
var combo = Array();
var comboSplit = keySplit[x].split('+');
// Save the key codes for each element in the key combo
for(y in comboSplit){
combo[y] = keyCodes[ comboSplit[y] ];
}
keySplit[x] = combo;
} else {
//Otherwise, it's just a normal, single key command
keySplit[x] = keyCodes[ keySplit[x] ];
}
}
return this.each(function() {
$this = $(this);
// Create active keys array
// This array will store all the keys that are currently being pressed
var activeKeys = Array();
$this.keydown(function(e){
// Save the current key press
activeKeys[ e.keyCode ] = e.keyCode;
if($.inArray(e.keyCode, keySplit) > -1){ // If the key the user pressed is matched with any key the developer set a key code with...
if(typeof callback == 'function'){ //and they provided a callback function
callback(); //trigger call back and...
e.preventDefault(); //cancel the normal
}
} else { // Else, the key did not match which means it's either a key combo or just dosn't exist
// Check if the individual items in the key combo match what was pressed
for(x in keySplit){
if($.inArray(e.keyCode, keySplit[x]) > -1){
// Initiate the active variable
var active = 'unchecked';
// All the individual keys in the combo with the keys that are currently being pressed
for(y in keySplit[x]) {
if(active != false) {
if($.inArray(keySplit[x][y], activeKeys) > -1){
active = true;
} else {
active = false;
}
}
}
// If all the keys in the combo are being pressed, active will equal true
if(active === true){
if(typeof callback == 'function'){ //and they provided a callback function
callback(); //trigger call back and...
e.preventDefault(); //cancel the normal
}
}
}
}
} // end of if in array
}).keyup(function(e) {
// Remove the current key press
activeKeys[ e.keyCode ] = '';
});
});
}
})(jQuery);
This is just a shot in the dark but maybe it'll help you down the right path.
If it's possible to have that function recognize a hexadecimal value for the key that you entered instead of the literal key (such as 0x6E for the letter 'n'), you could derive what "alt+n" translates to in hex and have the function look out for that value.
If you're looking for something that will let a user easily enter and define key combos using a plain input box, I wrote a plugin that does it for you: http://suan.github.com/jquery-keycombinator/