[英]Javascript on key press trigger only once
I don't know why this appears to be so difficult to figure out. 我不知道为什么这似乎很难弄清楚。 I want to be able to execute code when a key is pressed and held but only once.
我希望能够在按住某个键(但只能一次)时执行代码。 Instead when I use
onkeypress
or onkeydown
the function that I bound gets executed repeatedly which is not what I want. 相反,当我使用
onkeypress
或onkeydown
,绑定的函数会重复执行,这不是我想要的。 How can I have the handler be executed just once when the key is held down? 按下键后,如何只执行一次处理程序?
Note: I don't want to embed logic into the function that will limit its execution, I want it not to be firing the event more than once no matter how long I hold the key. 注意:我不想将逻辑嵌入到会限制其执行的函数中,我希望无论我按住该键多长时间,它都不会多次触发该事件。
Here is the demo and the code 这是演示和代码
HTML 的HTML
<div id="counter">0</div>
JS JS
var counter = 0,
div = document.getElementById('counter');
document.body.onkeypress = function(){
div.innerHTML = counter++;
}
Notice how when you press and hold any key the counter keeps going, I want it to count just once no matter how long I hold the key, and keep in mind the notice from above. 请注意,当您按住任意键时,计数器将继续运行,无论我按住该键多长时间,我都希望它只计数一次,并记住上面的提示。
Sorry forgot to mention removing the listener is not acceptable, I need to increase the counter by 1 every time a key is pressed but no matter how long it's held. 对不起,忘了提到删除监听器是不可接受的,我需要在每次按下一个键时将计数器增加1,但无论它保持多长时间。
You do have to use logic to avoid repetitive events on a key being pressed, because there's no specific and compatible event for key being just pressed. 你必须用逻辑来避免重复事件上的一个键被按下,因为没有具体的和兼容事件关键被刚刚按下。
More specifically, the easiest solution is to store a boolean, setting it true on key up, false on key down (after having done your action), and ignoring the key down event while it's false: 更具体地说,最简单的解决方案是存储一个布尔值,在按下键时将其设置为true,在按下键时将其设置为false(在完成操作后),并在设置为false时忽略键按下事件:
(function(){
var shouldHandleKeyDown = true;
document.onkeydown = function(){
if (!shouldHandleKeyDown) return;
shouldHandleKeyDown = false;
// HANDLE KEY DOWN HERE
}
document.onkeyup = function(){
shouldHandleKeyDown = true;
}
})();
EDIT for 2019 编辑2019
Now that IE is dead, you can also use the event.repeat
property , which is true when the event is a repetition. 既然IE已死,您还可以使用
event.repeat
属性 ,当事件是重复事件时为true。
JSFiddle: http://jsfiddle.net/ts7w58od/ JSFiddle: http : //jsfiddle.net/ts7w58od/
1. Bind listener 1.绑定监听器
2. Unbind when event is fire. 2.事件发生时解除绑定。
var element = document.getElementById('target'),
once = function () {
console.log('once');
element.removeEventListener('keypress', once);
};
element.addEventListener('keypress', once, false);
This is a modified version of Denys Séguret answer 这是DenysSéguret答案的修改版本
let shouldHandleKeyDown = true; let n = 0; document.addEventListener('keydown', function() { if (!shouldHandleKeyDown) return; shouldHandleKeyDown = false; document.getElementById('counter').innerHTML = ++n; }); document.addEventListener('keyup', function () { shouldHandleKeyDown = true; });
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Counter</title> </head> <body> Counter : <span id=counter>0</span> </body> </html>
The easiest way to handle this is by using the repeat
property in the event: 解决此问题的最简单方法是在事件中使用
repeat
属性:
// I'd recommend using addEventListener instead, but
// this is as close to the original code as possible
document.body.onkeypress = function (event) {
if (!event.repeat) {
div.innerHTML = counter++;
}
}
event.repeat
is false for the very first event, and true for repeated events (the ones that are fired when you hold down a key). event.repeat
对于第一个事件为false,对于重复事件为true(按住键时将触发)。
Another option is to use keyup
, which is always only used once, since you can't "hold up" a key, so it's never repeated (but keyup
is a bad choice for eg buttons, because it can break keyboard navigation compared to keypress
). 另一个选择是使用
keyup
,由于您无法“按住”键,因此始终仅使用一次,因此永远不会重复使用(但是keyup
对于例如按钮来说是一个不好的选择,因为与keypress
相比,它可能破坏键盘导航)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.