Reputation:
focus()
works but it can cause some problems.I want keycode and mouse click to work all the time. Independently of each other, it will click on the button when I press the "space" button and when I click the mouse, it will click on the button.
let testKey = document.querySelector(".switch-btn");
["click", "keypress"].forEach(ev => {
testKey.addEventListener(ev, function(e) {
if(ev == "click") {
console.log("click");
if(!testKey.classList.contains("slide")) {
testKey.classList.add("slide");
} else {
}
}
if(e.keyCode === 32) {
console.log("click, space");
}
});
});
<button class="switch-btn">
<span>
Play
</span>
<span>
pause
</span>
<span class="switch"></span>
</button>
Upvotes: 0
Views: 2430
Reputation: 5425
The keypress
event is deprecated and no longer recommended (See Document: keypress event documentation). Instead you can use the keydown
event.
If your intention is to handle the click
and keydown
events separately then you should check the detail
property for the click
event handler. If the button is clicked the property will have a value of 1
. (See UIEvent.detail documentation)
Unless the user focuses on the button using the tab key, the keydown
event is not going to fire your handler. Adding a handler at the container or document level can overcome this. In the code below I have added such a handler and called the stopPropagation
method within the handler on the button to prevent the event bubbling up to the document level.
let testKey = document.querySelector(".switch-btn");
document.addEventListener('keydown', function(e) {
if(e.keyCode === 32) {
console.log("document: space pressed");
doTheClassListThing();
}
});
["click", "keydown"].forEach(ev => {
testKey.addEventListener(ev, function(e) {
if(ev == "click" & e.detail == 1) {
console.log("click");
doTheClassListThing();
}
if(e.keyCode === 32) {
e.stopPropagation();
console.log("Button: space keydown");
doTheClassListThing();
}
});
});
function doTheClassListThing() {
console.log('doTheClassListThing() executed');
if(!testKey.classList.contains("slide")) {
testKey.classList.add("slide");
} else {
}
}
<button class="switch-btn">
<span>
Play
</span>
<span>
pause
</span>
<span class="switch"></span>
</button>
Upvotes: 1
Reputation: 27245
I'm not sure I understand the question, but the reason the key doesn't register initially is because the button isn't focused. You could try calling testKey.focus()
to ensure it's initially focused.
I do not recommend this approach--forcing focus on the button could create accessibility issues and interfere with other element interactions, but here's a snippet just to demonstrate how focusing the button resolves the issue.
I agree with Terry's comment below, that attaching event handlers on body would be less fraught.
let testKey = document.querySelector(".switch-btn");
testKey.focus();
["click", "keypress"].forEach(ev => {
testKey.addEventListener(ev, function(e) {
if(ev == "click") {
console.log("click");
if(!testKey.classList.contains("slide")) {
testKey.classList.add("slide");
} else {
}
}
if(e.keyCode === 32) {
console.log("click, space");
}
testKey.focus();
});
});
<button class="switch-btn">
<span>
Play
</span>
<span>
pause
</span>
<span class="switch"></span>
</button>
Upvotes: 0