Предотвратить многократную обработку события нажатия клавиш JavaScript, удерживая нажатой - PullRequest
16 голосов
/ 22 мая 2011

У меня есть этот код:

else if (e.keyCode == 32){
      fired = true;

В функции keyDown (я добавил код document.addEventListener).Теперь он работает просто отлично, и делает именно то, что я хочу.Но вот в чем проблема: если вы удерживаете нажатой клавишу, она снова и снова будет выдавать значение fired = true до тех пор, пока оно не будет отпущено.Я просто хочу, чтобы он установил fired = true;один раз, даже если клавиша удерживается нажатой.

Ответы [ 7 ]

18 голосов
/ 22 мая 2011
    var fired = false;

    element.onkeydown = function() {

        if(!fired) {
            fired = true;
            // do something
        }
    };

Тогда используйте событие onkeyup

    element.onkeyup = function() {
     fired = false;
    };
6 голосов
/ 07 июля 2016

Если совместимость браузера не является вашей главной проблемой *, вы можете попробовать получить доступ к свойству .repeat KeyboardEvent, как описано здесь:
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/repeat

Делая что-то подобное в функции-обработчике:

function keyDown (e) {
  if (e.repeat) { return }

  // do stuff here
}

Вы можете избежать повторных нажатий клавиш.


*: на сайте MDN говорится, что он работает в Firefox, и я успешно использовал его в Chrome, поэтому у двух основных браузеров с ним не должно возникнуть проблем

3 голосов
/ 27 декабря 2015

Попробуйте это:)

Вы можете определить где-либо еще в вашем скрипте, не нажата ли клавиша, просто определив, истинно ли keydown! Вы также можете выполнить дополнительный сценарий, когда клавиша не работает, заменив console.log(); тем, что вы хотите выключить, когда клавиша не работает.

Скажите, пожалуйста, можно ли это улучшить.

var keydown = false;
window.addEventListener('keydown', function() {
  if (!keydown) {
    keydown = true;
    console.log('key down');
  }
  window.addEventListener('keyup', function() {
    keydown = false;
  });
});
1 голос
/ 20 августа 2017

Решения выше не учитывают многократное нажатие клавиш (представьте себе игру, в которой пользователь может нажимать вверх и влево одновременно, но оба должны быть запущены только один раз).Мне нужно было универсальное решение для отключения многократного нажатия клавиш для нескольких клавиш. Нажмите для ВСЕХ клавиш:

// create an array with 222 (number of keycodes) values set to true
var keyEnabledArray = Array(222).fill(true);

document.onkeydown = function(e){
    // disable the key until key release
    if(keyEnabledArray[e.keyCode]) {
        keyEnabledArray[e.keyCode] = false;
    }
};

document.onkeyup = function(e){
    // enable the specific key on keyup
    keyEnabledArray[e.keyCode] = true;
}; 

Проверьте фрагмент кода ниже:

// create an array with 222 true values
var keyEnabledArray = Array(222).fill(true);

document.onkeydown = function(e){
    // disable the key until key release
    if(keyEnabledArray[e.keyCode]) {
        keyEnabledArray[e.keyCode] = false;
        document.getElementById('console').innerHTML += e.keyCode + '<br>';
    }
    
};

document.onkeyup = function(e){
    keyEnabledArray[e.keyCode] = true;
};
Press a key:
<div id='console'></div>
1 голос
/ 23 октября 2014

Другой подход к решению этой проблемы (предложенный моим другом):

  1. Обратите внимание на метку времени, когда каждый раз происходит событие нажатия клавиши

  2. РассчитатьРазница между текущей меткой времени (t2) и предыдущей меткой времени (t1)

  3. (a) Если разница меньше некоторого заранее определенного порога, то это вторая клавиша (значит, мы ужевыполнил код для этого события).Следовательно, мы можем решить не выполнять код снова

    (b) Если разница больше, чем предопределенное пороговое значение, то это первое нажатие клавиши.Следовательно, мы выполнили бы код

1 голос
/ 22 мая 2011

Использовать keyup событие. Он срабатывает, когда они поднимают ключ.

0 голосов
/ 28 ноября 2018

Чтобы избежать повторения события keydown, заблокируйте его после выстрела и разблокируйте его с помощью keyup.Вам следует избегать глобальной переменной 'fired', поэтому используйте кодовый блок с ES6 + или закрытие в более старой версии JS.

Для ES6:

{ let fired = false;    // code block to exclude 'fired' from global scope
    element.addEventListener('keydown', (e) => {
        // only accept key down when was released
        if(!fired) {
            fired = true;
            // check what key pressed...
            if (e.keyCode === 32) {
                // and do what you need with it
            }
        }
    });

    element.addEventListener('keyup', (e) => {
        fired = false;
    });
}

Для более старой версии JS используйте IIFE:

(function(){
    let fired = false;
    element.addEventListener('keydown', function(e) {
        // only accept key down when was released
        if(!fired) {
            fired = true;
            // check what key pressed...
            if (e.keyCode === 32) {
                // and do what you need with it
            }
        }
    });

    element.addEventListener('keyup', function(e) {
        fired = false;
    });
})();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...