按住键时忽略重复的键盘事件

时间:2019-06-28 10:17:17

标签: javascript jquery

我的以下代码在按 Ctrl + Shift + Enter 时会触发update_doc_text(),似乎多次调用了该函数对于某些用户(当我同时按住这些键时也会发生)。如何确保该功能仅执行一次?

var ctrlDown = false,
  ctrlKey = 17,
  shiftDown = false,
  shiftKey = 16,
  KeyEnter = 13,

  $(document).keydown(function(e) {
    if (e.keyCode == ctrlKey)
      ctrlDown = true;

    if (e.keyCode == shiftKey)
      shiftDown = true;

    if (ctrlDown && shiftDown && (e.keyCode == KeyEnter))
      update_doc_text();
  }).keyup(function(e) {
    if (e.keyCode == ctrlKey)
      ctrlDown = false;

    if (e.keyCode == shiftKey)
      shiftDown = false;
  });

2 个答案:

答案 0 :(得分:1)

问题出在逻辑的结构上。它要复杂得多。

您可以通过从事件中读取ctrlKeyshiftKey标志来确保满足需要,以确保在按下回车键的同时将它们按住。

要避免在按住键时重复,可以使用setTimeout()来设置一个标志,该标志将在指定的时间内禁用重复操作。试试这个:

$(document).keydown(function(e) {
  var $doc = $(this);
  if (e.ctrlKey && e.shiftKey && e.which === 13 && !$doc.data('ctrlShiftReturnDisabled')) {
    update_doc_text();
    
    $doc.data('ctrlShiftReturnDisabled', true);
    setTimeout(function() {
      $doc.data('ctrlShiftReturnDisabled', false);
    }, 2000); // 2 seconds, change as needed
  }
});

function update_doc_text() {
  console.log('update_doc_text');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

答案 1 :(得分:1)

您可以使用对象来存储按下的键并通过e.which属性获取键代码。另外,您可以使用一个变量pressed来跟踪按键是否被按下,并仅在该变量为false时运行代码。

var keys = {}, pressed = false, codes = [13, 16, 17]
var check = keys => codes.every(k => keys[k]);

$(document).keydown(function(e) {
  keys[e.which] = true;

  if (check(keys) && !pressed) {
    // run your code here
    console.log('pressed')
    pressed = true;
  }

}).keyup(function(e) {
  keys[e.which] = false;

  if (codes.includes(e.which)) {
    pressed = false
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>