Event Handling in Javascript using buttons - javascript

I have two functions that have if statements inside them. I am trying to choose which function to run based off which keys are pressed. When ran the keys without shift override the shift if statements. I am sure to solve this an event handler should be used. However I am not sure where to even start. If the standard ifs are taken out the shift if statements work and vice versa.
Individually each function works as intended. I have looked into adding an event handler based off what is pressed which function overrides which. I have looked at Event Handing and not really sure where to begin.
var map = {};
onkeydown = onkeyup = function(e){
e = e || event; //deals with IE Compatibility
map[e.key] = e.type == 'keydown';
}
I have an array that maps the keys that are pressed since there are more than one key that can be pressed at a specific time.
document.onkeydown = function (e){
if(e.which == 16 && e.which == 117){ //ShiftF6
try {
document.querySelectorAll("input[value=Close]")[0].click();
console.log("Button clicked.");
} catch(ex) {
};
try {
// eslint-disable-line prefer-template
document.querySelectorAll("textarea[name=bugnote_text]")[0].value = //display text
document.querySelectorAll("input[value='Close Ticket']")[0].click();
console.log("Button clicked.");
} catch(ex) {
};
}
This is an example of what is being done with shift and a simple function key.
document.onkeydown = function(zEvent){
if(zEvent.which == 117){ //F6
try {
document.querySelectorAll("input[value=Close]")[0].click();
console.log("Button clicked.");
} catch(ex) {
};
try {
// eslint-disable-line prefer-template
document.querySelectorAll("textarea[name=bugnote_text]")[0].value = //Display text;
document.querySelectorAll("input[value='Close Ticket']")[0].click();
console.log("Button clicked.");
} catch(ex) {
};
}
This is just a single button press.
Note there are multiple if statements inside each function no more than 5 in each however. I know placing these statements in a switch or array would probably be cleaner. I am trying to just decide which function to work out of depending which buttons are being pressed. I am not sure where to begin to get it to choose which way to go.

Related

How to trigger an html button and its onclick function with a hardware keyboard key?

I'm a newbie to coding, and this topic is probably very common, but it has me pretty confused.
I have a button:
<button onclick = typeWriter()>/click</button>`
My function:
var myArray = ['such', 'something else', ];
var rand = myArray[Math.floor(Math.random() * myArray.length)];
var i = 0;
var speed = 55;
function typeWriter() {
if (i < rand.length) {
document.getElementById("question").innerHTML += rand.charAt(i);
i++;
setTimeout(typeWriter, speed);
}
}
How do I add a keyboard key like the spacebar as an event listener or something similar, so that when I press the spacebar (and not in a text box), it presses the button and triggers the function? A simple vanilla javascript answer would be preferable, since I don't get jQuery.
Would it be better to simply add script that triggers myFunction with the spacebar rather than going through triggering the button? And if so, how do I program that?
BTW: I'm trying to do this for mobile, using an iPad keyboard. Will that change anything?
Thanks.
You can add a listener on window if you want to trigger your function everywhere of your html.
window.onkeydown = function(event) {
if (event.keyCode == 32) {
//your function here
};
};
Here you can find all key codes for keyboard: https://keycode.info/
don't use inline JS
Use addEventListener()
Use Event.key to determine the pressed key
Use a helper function to determine if the current Event.target is a FormElement
// Function to detect if el is a form element
const isFormElement = el => /^(input|textarea|select|button)$/i.test(el.nodeName);
// Example function
const myFunction = ev => console.log("HELLO!");
// Find buttons in DOM
const EL_myfn = document.querySelectorAll('.js-myFunction');
// Trigger directly on buttons click
EL_myfn.forEach(el=> el.addEventListener('click', myFunction));
// And on keydown
window.addEventListener('keydown', ev => {
// If spacebar is hit, and we're not inside a forminput element
if (ev.key === " " && !isFormElement(ev.target)) {
myFunction();
}
})
textarea{width: 100%;}
<button class="js-myFunction">Click me! (Console should log)</button>
<div>press spacebar here (Console should log)</div>
<textarea>press spacebar here (Console should not log!!)</textarea>

JS keylogger not accepting keyup correctly

I'm pretty new to JS, so I could have made some sort of silly error, but my keylogger doesn't seem to be functioning correctly. It accepts multiple keystrokes correctly, but when one is released, it recognizes both as up. Any help?
Here is my code:
var keymap = {};
onkeydown = onkeyup = function(e){
keymap[e.keyCode] = e.type == 'keydown';
if(keymap[39] && keymap[32]){ // Right+Space
jumpRight();
}
if(keymap[37] && keymap[32]){ // Left+Space
jumpLeft();
}
if(keymap[32]){ // Space
jump();
}
if(keymap[39]){ // Right
right();
}
if(keymap[37]){ // Left
left();
}
}
I'm using Google Chrome, if that helps any.
Thanks!
I think it's recognizing keystrokes correctly, because the array is being updated correctly. The problem is that your functions (left(), right(), jump(), etc.) are only firing when a keypress event happens. When you hold down a key, sometimes it will keep firing keydown events, and sometimes it won't. This causes the functions not to fire, even though your program knows that the key is being held down.
Working example (shows the array values all the time, not just on keypresses; shown array value doesn't necessarily mean the function fires):
var keymap = {};
onkeydown = onkeyup = function(e){
keymap[e.keyCode] = e.type == 'keydown';
if(keymap[39] && keymap[32]){ // Right+Space
jumpRight();
}
if(keymap[37] && keymap[32]){ // Left+Space
jumpLeft();
}
if(keymap[32]){ // Space
jump();
}
if(keymap[39]){ // Right
right();
}
if(keymap[37]){ // Left
left();
}
}
document.onkeydown=onkeydown;
document.onkeyup=onkeyup;
function jump(){}
function left(){}
function right(){}
function jumpLeft(){}
function jumpRight(){}
setInterval(function(){console.log(keymap[37]," ",keymap[32]," ",keymap[39]);},5);
Nonworking example (how it is right now, shows array values only on keypresses; shown array value == function fires):
var keymap = {};
onkeydown = onkeyup = function(e){
keymap[e.keyCode] = e.type == 'keydown';
if(keymap[39] && keymap[32]){ // Right+Space
jumpRight();
}
if(keymap[37] && keymap[32]){ // Left+Space
jumpLeft();
}
if(keymap[32]){ // Space
jump();
}
if(keymap[39]){ // Right
right();
}
if(keymap[37]){ // Left
left();
}
}
document.onkeydown=onkeydown;
document.onkeyup=onkeyup;
function jump(){console.log("jump");}
function left(){console.log("left");}
function right(){console.log("right");}
function jumpLeft(){console.log("jumpleft");}
function jumpRight(){console.log("jumpright");}
Note how in the nonworking example, the logging only happens on keydown events, which is when your functions will be called. In the "working" example, the logging happens regardless of key events, but your functions will still fail to fire, since they still happen when key events do. Here's a fully working example:
var keymap = {};
onkeydown = onkeyup = function(e){
keymap[e.keyCode] = e.type == 'keydown';
}
document.onkeydown=onkeydown;
document.onkeyup=onkeyup;
function jump(){console.log("jump");}
function left(){console.log("left");}
function right(){console.log("right");}
function jumpLeft(){console.log("jumpleft");}
function jumpRight(){console.log("jumpright");}
function main(){
if(keymap[39] && keymap[32]){ // Right+Space
jumpRight();
}
if(keymap[37] && keymap[32]){ // Left+Space
jumpLeft();
}
if(keymap[32]){ // Space
jump();
}
if(keymap[39]){ // Right
right();
}
if(keymap[37]){ // Left
left();
}
}
setInterval(main,250);
Hope this helps!
Good luck learning more JS!
P.S.: You labeled left() as "space". :P

Use a preventdefault to get out of the loop after pressing Enter key

This is a complete revision of my initial question, all unnecessary resources and references were deleted
I am tying the same event listener to 2 different elements: a button and Enter key, and it looks like the following:
var funcelement = function(){
//function code
};
$('#buttonID').click(funcelement);
$('#inputID').keyup(function () {
if (event.which == 13) {
$('#buttonID').trigger('click');
}
})
What I am trying to do is to prevent propagation of the enter key press if focus is on the submit button(#buttonID) by using preventDefault().
So I tried various combinations to make it work. The following is the latest result on my attempts
$('#inputID').keyup(function () {
var hasfocus = $('#buttonID').is(':focus') || false;
if (event.which == 13) {
if (!hasfocus) {
event.preventDefault();
$('#buttonID').trigger('click');
//hasfocus = true;
}
else {
//event.preventDefault();
//$('#buttonID').trigger('click');
}
}
})
After I enter a text into an input box and press Enter key, a confirmation window with yes/cancel buttons pops up with focus on yes button. Once I press Enter again, another window confirming that changes were made pops up with Ok button focused on it. Once I press Enter again, everything I need is being made.
However, there is one problem: after the last step is done, I am going back to the if (!hasfocus) line.
How do I prevent that from happening? Once the stuff I need is done - I don't want to go into that line again.
You can pass a parameter to into the function and stop the propagation there like so:
var funcelement = function(event, wasTriggeredByEnterKey){
if (wasTriggeredByEnterKey && $('#buttonID').is(':focus')) {
event.stopPropagation;
}
//function code
};
$('#buttonID').click(funcelement);
$('#inputID').keyup(function () {
if (event.which == 13) {
$('#buttonID').trigger('click', [true]);
}
}
)
UPDATE
In order to answer your revised issue, you should use the "keydown" event rather than "keyup" when working with alerts. This is because alerts close with the "keydown" event but then you are still triggering the "keyup" event when you release the enter key. Simply change the one word like this:
$('#inputID').keydown(function () {
var hasfocus = $('#buttonID').is(':focus') || false;
if (event.which == 13) {
if (!hasfocus) {
event.preventDefault();
$('#buttonID').trigger('click');
//hasfocus = true;
}
else {
//event.preventDefault();
//$('#buttonID').trigger('click');
}
}
})

How to track modifier keys using javascript/jquery?

My requirement is just easy: user press Ctrl key some notification appear on my page, and when released the notifications just disappear, so i need to track modifier keys such as Ctrl. Unfortunately i google and didn't find any clues, some famous keyboard libs such as Mousetrap and keymaster seem also does not cover this topic.
Any ideas?
Modifier keys trigger keydown (but not keypress). Then you can simply check the flags defined on the event object. shiftKey, altKey, ctrlKey, metaKey, etc.
A full list is here: http://api.jquery.com/category/events/event-object/
With jQuery, you can just use the keydown and keyup event handlers and you will see the Ctrl key go down and up. If you want to keep track of whether it's down or up, then just set a global flag when it goes down and clear the flag when it goes up.
Example code:
$(document).keydown(function(e) {
if (e.which == 17) {
$("#result").append("ctrl key pressed<br>");
}
});
JQuery doc on e.which: http://api.jquery.com/event.which/
Working demo: http://jsfiddle.net/jfriend00/mezwF/
Try this-
var ctrlKey = false;
window.onkeydown = function(e) {
if(e.keyCode == 17) {
ctrlKey = true;
}
};
window.onkeyup = function(e) {
if(e.keyCode == 17) {
ctrlKey = false;
}
};
function notify() {
if(ctrlKey) {
$('#notification').show();
} else {
$('#notification').hide();
}
}
function main() {
var _inter = setInterval(notify, 100);
}
main();

Why does Javascript drop keyUp events when the metaKey is pressed on Mac browsers?

On Mac browsers, javascript does not receive keyup events for most keys (other modifier keys seem to be an exception) when the metakey is down. Use this jsfiddle to demonstrate (focus the result area and try something like cmd + x, the x will not receive a keyup event):
http://jsfiddle.net/mUEaV/
I've reproduced this in stable releases for Chrome, FF, Safari and Opera. The same thing does not seem to happen with the control key in Windows 7.
Is the OS hijacking the keyup event? This seems especially strange since commands that use the metakey such as save, find, cut, copy, etcetera all activate on keydown not on keyup, and can be hijacked by the javascript just fine.
It's simply not possible to get the onKeyUp events when meta is used, I learned today. Very unfortunate and difficult to work around. You'll have to emulate them some other way.
Edit: To clarify, this is only on Mac and occurs due to OS level handling of the event. It cannot be overridden. Sorry to be the bearer of bad news.
Although event.metaKey returns false, event.keyCode and event.key are still populated.
document.addEventListener('keyup', function(e) {
console.log(e.metaKey || e.key);
});
Click here then press the Command, Control, or Option keys.
Is the browser window retaining the focus when you press those keys? In windows you can get similar result when pressing windows+R or CTRL+ESC and similar key combinations that make browser to loose focus and that results in missed events.
While keyup events are indeed not available when the meta key is pressed, you can still get keydown events for all keys, as well as keyup events for the meta key itself.
This allows us to just simply keep track of the state of the meta key ourselves, like so:
let metaKeyDown = false;
window.addEventListener("keydown", event => {
if (event.key == 'Meta') { metaKeyDown = true; }
});
window.addEventListener("keyup", event => {
if (event.key == 'Meta') { metaKeyDown = false; }
});
By now additionally checking for the main key, plus cancelling the default behavior with Event.preventDefault() we can easily listen for key combinations (like here e.g. CMD+K) and prevent the browser from handling them:
let metaKeyDown = false;
window.addEventListener("keydown", event => {
if (event.key == 'Meta') { metaKeyDown = true; }
if (event.key == 'k' && metaKeyDown) {
event.preventDefault();
console.log('CMD+K pressed!');
}
});
window.addEventListener("keyup", event => {
if (event.key == 'Meta') { metaKeyDown = false; }
});
(Note the observation of the k key taking place already on keydown.)
Also, please be aware that when used incorrectly, this can break standard browser functionality (e.g. like CMD+C or CMD+R), and lead to poor user experience.
You can create an artificial keyup event by waiting for a certain period after the last keydown event. The only caveat is people will have different repeat rates on their os.
https://jsfiddle.net/u7t43coz/10/
const metaKeyCodes = ["MetaLeft", "MetaRight"];
const shiftKeyCodes = ["ShiftLeft", "ShiftRight"];
const ctrlKeyCodes = ["ControlLeft", "ControlRight"];
const altKeyCodes = ["AltLeft", "AltRight"];
const modifierKeyCodes = [
...metaKeyCodes,
...shiftKeyCodes,
...ctrlKeyCodes,
...altKeyCodes
];
// record which keys are down
const downKeys = new Set()
const artificialKeyUpTimes = {}
function onKeydown(e) {
downKeys.add(e.code);
// do other keydown stuff here
console.log("meta", e.metaKey, e.code, "down")
// check if metaKey is down
if (metaKeyCodes.some(k => downKeys.has(k))) {
downKeys.forEach(dk => {
// we want to exclude modifier keys has they dont repeat
if (!modifierKeyCodes.includes(dk)) {
// fire artificial keyup on timeout
if (!artificialKeyUpTimes[dk])
setTimeout(
() => fireArtificialKeyUp(dk, e),
500
);
artificialKeyUpTimes[dk] = Date.now();
}
});
}
}
function fireArtificialKeyUp(code, e) {
// if enough time has passed fire keyup
if (Date.now() - artificialKeyUpTimes[code] > 100) {
delete artificialKeyUpTimes[code];
//if key is still down, fire keyup
if (downKeys.has(code)) {
const eCode = isNaN(code) ? { code: code } : { keyCode: code };
document.dispatchEvent(
new KeyboardEvent("keyup", { ...e, ...eCode })
);
}
} else {
setTimeout(() => fireArtificialKeyUp(code, e), 100);
}
}
function onKeyup(e) {
downKeys.delete(e.code);
// do keyup stuff here
console.log("meta", e.metaKey, e.code, "up")
}
document.addEventListener("keydown", onKeydown)
document.addEventListener("keyup", onKeyup)

Categories

Resources