«Глюки» при использовании onkeydown с несколькими клавишами - PullRequest
0 голосов
/ 14 июня 2019

При удерживании одной клавиши со стрелкой функция работает правильно.

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

Упрощенная версия моих функций выглядит следующим образом:

document.body.onkeyup = function(e){  
  if ([37,38,39,40].indexOf(e.keyCode) > -1){
    var key_pressed = e.keyCode || e.which;
    console.log(key_pressed + " is UP")
  }

  if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
    e.preventDefault();
  }
};


document.body.onkeydown = function(e){  
  if ([37,38,39,40].indexOf(e.keyCode) > -1){
    var key_pressed = e.keyCode || e.which;
    console.log(key_pressed + " is DOWN")
  }

  if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
    e.preventDefault();
  }

};

Так что, если я удерживаю клавишу со стрелкой ВВЕРХ, он постоянно повторяет 38 is DOWN, пока я держу клавишу.
Затем, если я нажимаю ПРАВУЮ кнопку со стрелкой, она повторяет 39 is DOWN, пока я держу обе клавиши.
Затем, если я отпускаю ПРАВУЮ клавишу со стрелкой, она говорит: 39 is UP.

Мойожидалось, что он продолжит повторять «1016» снова, так как я все еще держу стрелку ВВЕРХ.Однако этого не происходит.

Почему это происходит?Что я должен сделать, чтобы исправить это, чтобы моя клавиша со стрелкой все еще определялась как удерживаемая?

Ответы [ 3 ]

1 голос
/ 14 июня 2019

Инициализировать интервальный таймер для каждой клавиши со стрелкой, который запускается после их нажатия.

Сброс таймера интервала каждой стрелки после их отпускания:

var timer = [];
    
document.body.onkeyup = function(e){  
  let key = e.keyCode || e.which;
  if ([37,38,39,40].includes(key)) {
    console.log(key + " is UP");
    clearTimeout(timer[key]);      // stop this key's timer
    timer[key] = null;             // clear it so it can be initialized again
  }

  if ([32, 37, 38, 39, 40].includes(e.keyCode)) {
    e.preventDefault();
  }
};

document.body.onkeydown = function(e) {
  let key = e.keyCode || e.which;
  if ([37,38,39,40].includes(key) && !timer[key]) {
    clearTimeout(timer[key]);
    timer[key] = setInterval(() => {  // create a timer for this key
      console.log(key + " is DOWN")
    }, 100);
  }

  if ([32, 37, 38, 39, 40].includes(key)) {
    e.preventDefault();
  }
};
1 голос
/ 14 июня 2019

Клавиша со стрелкой все еще определяется как удерживаемая: событие keydown сработало, а событие keyup - нет.keyup и keydown срабатывают только тогда, когда что-то меняет , с одним исключением: генерируемые ОС события повторения клавиатуры.(Вы можете отфильтровать их, отметив e.repeat.)

Если вы хотите простой способ узнать, что в данный момент удерживается, вам придется самостоятельно поддерживать этот список:

const keysHeld = {};

document.body.addEventListener('keydown', evt => {
  keysHeld[evt.keyCode] = true;
});
document.body.addEventListener('keyup', evt => {
  keysHeld[evt.keyCode] = false;
});

(Обратите внимание, что keyCode устарело, и вы должны использовать code, если это возможно.)

0 голосов
/ 14 июня 2019

Вы можете обойти это поведение, отслеживая нажатые клавиши с помощью массива и просматривая массив с помощью таймера.

var keysDown = new Array();
document.body.onkeyup = function(e) {
  if ([37, 38, 39, 40].indexOf(e.keyCode) > -1) {
    var key_pressed = e.keyCode || e.which;

    for (var a = 0; a < keysDown.length; a++) {
      if (keysDown[a] == key_pressed) {
        keysDown.splice(a, 1);
      }
    }
  }

};

function update() {
  var message = "";
  for (var a = 0; a < keysDown.length; a++) {
    message += keysDown[a] + " is down ";

  }
  if (message != "") {
    console.log(message);
  }
}
var interval = setInterval(update, 20);

document.body.onkeydown = function(e) {
  if ([37, 38, 39, 40].indexOf(e.keyCode) > -1) {
    var key_pressed = e.keyCode || e.which;
    var found = false;
    for (var a = 0; a < keysDown.length; a++) {
      if (keysDown[a] == key_pressed) {
        found = true;
      }
    }
    if (!found) {
      keysDown.push(key_pressed)
    }
  }
};
...