简体   繁体   English

按键上的Java触发器仅触发一次

[英]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. 相反,当我使用onkeypressonkeydown ,绑定的函数会重复执行,这不是我想要的。 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. 注意:我不想将逻辑嵌入到会限制其执行的函数中,我希望无论我按住该键多长时间,它都不会多次触发该事件。

EDIT I 编辑我

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. 请注意,当您按住任意键时,计数器将继续运行,无论我按住该键多长时间,我都希望它只计数一次,并记住上面的提示。

EDIT II 编辑二

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;
    }
})();

Demonstration 示范

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM