I have setup a keypress event that should fire when the user clicks the right arrow key on the keyboard. For some reason it is not firing. Using Chrome dev tools confirms event is not firing. When the user presses the right key it should insert an image onto the webpage (and delete another image).
There is quite a lot of code so I apologise but I will only put in what I feel is relevant.
Here is the event listener:
document.addEventListener("keypress", (event) => {
if (event.keycode === 39 || event.which === 39) {
newPosition = `box-${currentPos + 1}`;
naviCtrl.removeCharacter(DOMstrings);
naviCtrl.rightBtn(currentPos, chosenCharacter, newPosition);
}
});
Here is the rightBtn method:
rightBtn: (currentPos, chosenCharacter, newPosition) => {
if (newPosition.style.border-left === "none" && currentPos.style.border-right === "none") {
document.getElementById(newPosition).insertAdjacentHTML("beforeend", '<img class="character-img character-box" src="' + chosenCharacter + '">');
console.log(newPosition);
The event listeners are setup when the page loads with this init function:
return {
init: () => {
setupEventListeners()
}
};
You can see, this method is called globally here:
appController.init();
The event listener keypress is deprecated, as is event.which. You should use (probably) use keydown in this instance, and the correct keycode for right arrow (ArrowRight), as follows:
document.addEventListener("keydown", (event) => {
if (event.keycode === "ArrowRight" || event.which === 39) {
newPosition = `box-${currentPos + 1}`;
naviCtrl.removeCharacter(DOMstrings);
naviCtrl.rightBtn(currentPos, chosenCharacter, newPosition);
}
});
Related
I am new to JavaScript and learning event handlers. How to detect click + specific key pressed concurrently? For example click+D, using pure (vanilla) js.
Edit:
I tried this way but its not detecting the click event when key is pressed.
The console.log("key "+keyPressed) statement is also executed continuously while key is in pressed state.
keyPressed=false;
function keyDown(event) {
var x = event.key;
if (x == "a" || x == "A") {
keyPressed=true;
console.log("key "+keyPressed);
}
}
function keyUp(event){
keyPressed=false;
console.log("key "+keyPressed);
}
function clickHelper(event){
console.log("---");
if(keyPressed){
console.log("*****");
}
}
IIRC you cannot use one event to detect if the mouse is held down AND a button is clicked. However, you can set a property called mouseDown of the document and register an event listener for mouse state.
var mouseDown = 0;
document.body.onmousedown = function () {
++mouseDown;
};
document.body.onmouseup = function () {
--mouseDown;
};
document.body.onkeydown = function (e) {
if (mouseDown && e.key === 'd') {
alert('D was pressed while clicking');
}
};
I used some code from this stackoverflow post for this.
I have the following code:
undoButton.onclick = undoFunction;
document.addEventListener("keydown", (e) => {
if ((e.ctrlKey || e.metaKey) && e.code === "KeyZ") {
e.preventDefault();
undoFunction();
}
});
function undoFunction() {
console.log("undo function...");
}
When I click the button, as excepted, the function code runs once, and so does the console.log, but when I use the key stroke, the function is running a multiple times, up to hundreds of so-called loops at some scenarios. Any suggestion why? I tried to used e.repeat = false but had no luck. Thanks!
Use keyup instead. The keydown event triggers as long a key is hold down. keyup only triggers when a key is released.
var undoButton = document.getElementById('undoButton');
undoButton.onclick = undoFunction;
document.addEventListener("keyup", (e) => {
if ((e.ctrlKey || e.metaKey) && e.code === "KeyZ") {
e.preventDefault();
undoFunction();
}
});
function undoFunction() {
console.log("undo function...");
}
<input id="undoButton" type="button" value="Undo" />
I have code for 3 different task which I want to execute by clicking and pressing a key, so there will be 3 different combination of clicking and pressing. For example-
window.addEventListener("keydown", function(e){
if(e.keyCode === 16) {console.log('Yap! Shift works...');}
if(e.keyCode === 17) {console.log('Yap! Ctrl works...');
document.addEventListener('click',function (event) {
console.log(event.target.className);
}, false);
}
},false);
Now, when I press click shift key, I get related output, when I click Ctrl key and then click, I get the class name of the object I click on.
But the problem is, the output keeps coming as much I hold the key!! I want to execute the part of my code for once, and exactly when the key is pressed and a clicked is occurred.
How can I do that?
In general, how can I execute 3 part of code for three different tasks by clicking and pressing efficiently?
Adding an event handler while handing an event, is often the wrong way to solve a problem. Imagine how you will accumulate adding handlers... in your case there will eventually be many bindings to the same click handler.
It is better to bind the handlers you need immediately, and then work with keeping state on what exactly needs to happen while handling the event.
In these key handlers (keydown, keyup), keep track of whether the Shift/Control keys are depressed or not.
Also, use e.key as e.keyCode is deprecated.
Here is how that could work:
let keys = {
"Shift": false,
"Control": false
};
function keyToggle(e) {
if (!(e.key in keys)) return; // not ctrl or shift
let isKeyDown = e.type === "keydown";
if (isKeyDown === keys[e.key]) return; // key position did not change
keys[e.key] = isKeyDown;
console.log(e.key + (isKeyDown ? " pressed" : " released"));
}
document.addEventListener("keydown", keyToggle, false);
document.addEventListener("keyup", keyToggle, false);
document.addEventListener('click', function (e) {
if (keys["Control"]) console.log(event.target.className);
}, false);
<main class="main">Main</main>
<aside class="aside">Aside</aside>
As you addEventListener you can also removeEventListener.
For that you need a reference to your event handler, so you cannot use anonymous functions, but named functions or functions stored in a variable.
Edit
Here is an example of using CTRL+click:
// CTRL + CLICK implementation
let hasCtrl = false;
// Store the handler in a constant or variable
const handleClick = function(event) {
console.log(event.target.className);
}
// Use named function
function handleKeyDown(e) {
if (e.keyCode === 16) {
console.log('Yap! Shift works...');
}
}
const setCtrlInactive = (e) => {
if (!hasCtrl && e.keyCode === 17) {
console.log('Nope! Ctrl does not work...');
document.removeEventListener('click', handleClick);
hasCtrl = true;
}
}
const setCtrlActive = (e) => {
if (hasCtrl && e.keyCode === 17) {
console.log('Yap! Ctrl works...');
document.addEventListener('click', handleClick);
hasCtrl = false;
}
}
document.addEventListener("keyup", setCtrlInactive);
document.addEventListener("keydown", setCtrlActive);
document.addEventListener("keydown", handleKeyDown);
<main class="main">Main</main>
<aside class="aside">Aside</aside>
Well you can easily create an variable to lock it:
var locked = false;
window.addEventListener("keydown", function(e){
if(e.keyCode === 16 && !locked) {console.log('Yap! Shift works...'); locked =
true;}
if(e.keyCode === 17 && !locked ) {console.log('Yap! Ctrl works...');
locked = true;
}
},false);
document.addEventListener('click',function (event) {
if(locked){
// do something
console.log(event.target.className);
}
}, false);
window.addEventListener("keyup", function(){
locked = false;
}
That's because you called addEventListener('click') in the keydown event handler.
let ctrl = false;
window.addEventListener("keydown", function(e) {
if (e.keyCode === 16) {
console.log('Yap! Shift works...');
}
if (e.keyCode === 17 && ctrl === false) {
console.log('Yap! Ctrl works...');
ctrl = true;
}
});
window.addEventListener("keyup", function(e) {
if (e.keyCode === 17) {
ctrl = false;
}
});
document.addEventListener('click', function(event) {
if (ctrl) {
console.log(event.target.className);
}
}, false);
Instead, you should use keyup event and flag variable.
I have a button that fires a "stopstart" function (animation). I also want to have a mouseless method to do this so I've bound the same function to the space bar. This works.
However if focus is on the button, and I press space - both events fire, can't work out how to stop this (the keypress event fires first - in chrome..)
Eventlistener code:
document.getElementById("stopstart").addEventListener("click",
function (event) {
stopstart();
}); //add event listener to "stopstart" button
document.addEventListener("keypress",
function (event) {
if (event.keyCode === 32) { //space key
stopstart();
}
}); //add spacekey event listener to document
I don't want to remove focus from the button, as I'd like to retain that functionality - the two events appear to be separately generated - so I haven't found how to detect that the click event was in fact generated by the space bar.
Is this solvable using without having to add temporary flags to catch it etc
The click location for key events is zero, zero so you can look for that.
document.getElementById("stopstart").addEventListener("click",
function (event) {
var x = event.x || event.clientX;
var y = event.y || event.clientY;
if (!x && !y) {
alert("key press");
return false;
}
stopstart();
});
http://jsfiddle.net/mScEC/
function (event) {
if (event.pointerType !== "mouse") return;
stopstart();
}); //add event listener to "stopstart" button
document.addEventListener("keypress",
function (event) {
if (event.keyCode === 32) { //space key
stopstart();
}
}); //add spacekey event listener to document```
You can simply use event.preventDefault() inside keypress event Listener to prevent the Button Click event from getting triggered on keypress
e.g
document.addEventListener('keydown', function (e) {
e.preventDefault();
if (e.key === 'Enter') {
try {
// if expression is not evaluated then catch block will be executed
screen.value = eval(screen.value);
}
catch (error) {
console.log(error.message);
screen.value = 'Invalid Operation';
}
}
})
I have a button in HTML and I want to provide a shortcut key to it, which should run the functionality as when button clicks what happens.
Is it possible to do something like this using JavaScript or jQuery.
You can do this using plain HTML: accesskey="x". Then you can use alt+x (depending on the browser though if it's alt or something else)
Untested:
$("body").keypress(function(event) {
if ( event.which == 13 ) { // put your own key code here
event.preventDefault();
$("#yourbutton").click();
}
});
It's pretty easy using jQuery. To trigger a button:
$('#my-button').trigger('click');
To monitor for keypress:
$(window).keypress(function (event) {
if (event.which === 13) { // key codes here: http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
event.preventDefault();
$('#my-button').trigger('click');
}
});
Now, if you want to use the Ctrl key or similar you use
if (event.which === 13 && event.ctrlKey)
and similar with event.altKey, event.shiftKey.
$(document).on('keypress', function (e) {
if (e.keyCode === youreKeyCodeHere) {
// if (e.keyCode === youreKeyCodeHere && e.shiftKey === ture) { // shift + keyCode
// if (e.keyCode === youreKeyCodeHere && e.altKey === ture) { // alt + keyCode
// if (e.keyCode === youreKeyCodeHere && e.ctrlKey === ture) { // ctrl + keyCode
$('youreElement').trigger('click');
}
});
Where youreKeyCode can be any of the following javascript char codes , if you're shortcut needs an alt (shift, ctrl ...) use the commented if's . youreElement is the element that holds the click event you whant to fire up.