案例受到打击:
如果您单击按钮,然后按住“ enter”键不放,则按钮的click事件将不断触发。
document.querySelector('button').addEventListener('click', function (e) {
console.log(1);
})
<button>press Enter</button>
没有jQuery,没有表单,没有输入。我想知道这是如何工作的以及如何防止它...
谢谢你。
答案 0 :(得分:2)
之所以发生这种情况,是因为按下按钮上的Enter会触发其单击事件,并且当您按住某个键时,会重复出现重复键并不断重复“键入”该键。
如果要在触发一次事件后的一段时间内忽略该事件,可以将代码添加到处理程序中以执行此操作:
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>
如果您从不从不按下按钮上的Enter来“单击”它(我不建议这样做,对于依靠键盘使用的残障人士来说可能会很困难),您可以防止按钮上的keydown
事件:
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>
另请参见vlaz's answer,它仅在按键重复时才阻止按键,这似乎是一个很好的折衷方案。
答案 1 :(得分:1)
这是由于单击按钮时出现的。按钮保持焦点状态
答案 2 :(得分:1)
修订后的答案::按住某个键时,您希望获得的事件顺序为keydown
-> keypress
-> keydown
- > keypress
->(...同样的两个事件重复出现...)-> keyup
。知道了这一点,您就可以跟踪在keydown
中按下的内容,并知道它最终以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>
这将在任何符合DOM Level 3的环境下运行,因此适用于所有主流浏览器。但是,according to MDN在某些较旧的环境中会将按下的键视为重复按下该键,每次发送keydown
-> keypress
-> keyup
。在这种情况下,您可以使用T.J. Crowder's solution which uses a timeout period。
如果使用ES6,则可以将按下的键存储在a Set中,并且可以将整个内容包装在一个封闭的容器中,以防止这些键可用于可能不需要它们的其他代码。
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>
原始答案:您可以通过查看Event.repeat
属性来防止按下键。但是,Edge或Internet Explorer不支持repeat
属性,因此只能在Chrome,Firefox和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>
如果您为按钮计时并按住Enter键甚至是空格键,则不会重复发生事件。
值得注意的是-您需要添加键盘事件(keydown
,keypress
或keyup
)的侦听器才能使用repeat
属性。 click
是一个没有repeat
的鼠标事件,因为它没有意义。
答案 3 :(得分:0)
由于按钮具有焦点,因此将每个事件(按Enter键)定向到该按钮并执行。为防止它多次发生,您可以使用blur()
除去焦点。然后,它只执行一次,直到用户再次将焦点放在按钮上。
document.querySelector('button').addEventListener('click',
function (e) {
console.log(1);
this.blur();
})