按键上的Javascript只触发一次

问题描述 投票:5回答:4

我不知道为什么这似乎很难弄明白。我希望能够在按下并按住键时执行代码,但只能执行一次。相反,当我使用onkeypressonkeydown时,我绑定的函数会被重复执行,这不是我想要的。当按住键时,如何只执行一次处理程序?

注意:我不想将逻辑嵌入到限制其执行的函数中,我希望它不会多次触发事件,无论我持有多长时间。

EDIT I

这是demo和代码

HTML

<div id="counter">0</div>

JS

var counter = 0,
    div = document.getElementById('counter');

document.body.onkeypress = function(){
    div.innerHTML = counter++;
}

请注意,当您按住任何键时,计数器会继续运行,无论我持有多长时间,我都希望它只计算一次,并记住上面的通知。

EDIT II

对不起忘了提到删除监听器是不可接受的,每次按下一个键时我都需要将计数器加1,不管它持有多长时间。

javascript
4个回答
4
投票

您必须使用逻辑来避免按下按键时出现重复事件,因为按下按键时没有特定且兼容的事件。

更具体地说,最简单的解决方案是存储一个布尔值,在key up时设置为true,在key down时设置为false(在完成操作之后),并在它为false时忽略key down事件:

(function(){
    var shouldHandleKeyDown = true;
    document.onkeydown = function(){
      if (!shouldHandleKeyDown) return;
      shouldHandleKeyDown = false;
      // HANDLE KEY DOWN HERE
    }
    document.onkeyup = function(){
      shouldHandleKeyDown = true;
    }
})();

Demonstration

编辑2019年

现在IE已经死了,你也可以使用the event.repeat property,当事件是重复时这是真的。


1
投票

JSFiddle:http://jsfiddle.net/ts7w58od/ 1.绑定听众 2.事件发生时解除绑定。

var element = document.getElementById('target'),
    once = function () {
        console.log('once');
        element.removeEventListener('keypress', once);
    };

element.addEventListener('keypress', once, false);

0
投票

这是Denys Sé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>

0
投票

处理此问题的最简单方法是在事件中使用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对于第一个事件是错误的,对于重复事件(按住键时触发的事件)是真的。

另一个选择是使用keyup,它总是只使用一次,因为你不能“撑起”一个键,所以它永远不会重复(但是keyup对于例如按钮来说是一个糟糕的选择,因为与keypress相比,它可以打破键盘导航)。

© www.soinside.com 2019 - 2024. All rights reserved.