How To Prevent Triggering Button Event When Press 'enter' Key And Hold?
Solution 1:
It happens because pressing Enter on a button triggers its click event, and when you hold a key, key repeat kicks in and keeps "typing" that key over and over.
If you want to ignore the event for a period of time after it's been triggered once, you can add code to your handler to do that:
var IGNORE_TIME = 1000; // One second
var lastClick = null;
document.querySelector('button').addEventListener('click', function (e) {
var now = Date.now();
if (!lastClick || now - lastClick > IGNORE_TIME) {
lastClick = now;
console.log(1);
}
});
<button>press Enter</button>
If you never want pressing Enter on the button to "click" it (which I don't recommend, you may make it difficult for someone with a disability who relies on using the keyboard), you can prevent the keydown
event on the button:
document.querySelector('button').addEventListener('click', function (e) {
console.log(1);
});
document.querySelector('button').addEventListener('keydown', function (e) {
var key = e.keyCode || e.charCode;
if (key == 13) {
e.stopPropagation();
e.preventDefault();
}
});
<button>press Enter</button>
See also vlaz's answer, which only prevents the keypress if it's from key repeat, which seems like an excellent compromise.
Solution 2:
This is due to the fact that when you click the button. the button keep the focus state
Solution 3:
Revised answer: When a key is held down, the sequence of events you would expect to get is keydown
-> keypress
-> keydown
-> keypress
-> (... same two events repeated ...) -> keyup
. Knowing that, you can keep track of what was pressed in keydown
and know that it finally ended in a keyup
.
document.querySelector('button').addEventListener('click', function (e) {
console.log(1);
});
var keysCurrentlyPressed = {};
document.querySelector('button').addEventListener('keydown', function (e) {
var key = e.keyCode || e.charCode;
if (keysCurrentlyPressed[key]) {
e.stopPropagation();
e.preventDefault();
} else { //this is the first time the key is pressed, add an entry for this key
keysCurrentlyPressed[key] = true;
}
});
document.querySelector('button').addEventListener('keyup', function (e) {
var key = e.keyCode || e.charCode;
delete keysCurrentlyPressed[key]; //note that the key isn't pressed any more
});
<button>press Enter</button>
This will work on any environment that is DOM Level 3 compliant, so all major browsers. However, according to MDN some older environments would treat a key pressed down as repeatedly pressing the key, sending keydown
-> keypress
-> keyup
each time. If that's the case, you can use T.J. Crowder's solution which uses a timeout period.
If using ES6, you can store the pressed keys in a Set and you can wrap the whole thing in a closure, to prevent the keys from being available to other code that probably doesn't need them.
document.querySelector('button').addEventListener('click', function (e) {
console.log(1);
});
(function() {
const keysCurrentlyPressed = new Set();
document.querySelector('button').addEventListener('keydown', e => {
const key = e.keyCode || e.charCode;
if (keysCurrentlyPressed.has(key)) {
e.stopPropagation();
e.preventDefault();
} else {
keysCurrentlyPressed.add(key);
}
});
document.querySelector('button').addEventListener('keyup', e => keysCurrentlyPressed.delete(e.keyCode || e.charCode));
})()
<button>press Enter</button>
Original answer: You can prevent a key being held down by looking at the Event.repeat
property. However, the repeat
property is not supported on Edge or Internet Explorer, so this will only work on Chrome, Firefox and Safari.
document.querySelector('button').addEventListener('click', function (e) {
console.log(1);
});
document.querySelector('button').addEventListener('keydown', function (e) {
if (e.repeat) { //don't do anything if a key is held down.
e.stopPropagation();
e.preventDefault();
}
});
<button>press Enter</button>
If you clock the button and hold down Enter or even Space, you won't get repeated events.
Worth noting - you need to add a listener for a keyboard event (keydown
, keypress
, or keyup
) to use the repeat
property. The click
is a mouse event which doesn't have a repeat
, as it makes no sense for it.
Solution 4:
As the button has focus, every event (as is pressing Enter) is directed to that button and executed. To prevent it from happening multiple times, you can remove the focus by using blur()
. It then executes only once, untill the user sets focus on the button again.
document.querySelector('button').addEventListener('click',
function (e) {
console.log(1);
this.blur();
})
Post a Comment for "How To Prevent Triggering Button Event When Press 'enter' Key And Hold?"