"Glitches" 使用具有多个键的 onkeydown 时



当按住单个箭头键时,函数可以正常工作。

但是,当我按住第二个箭头键并释放第二个键时,就会出现问题,因为第一个键不再被检测到。

我的函数的简化版本如下:

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.

我的期望是让它继续重复说38 is DOWN,因为我仍然持有向上箭头。但是,它不会这样做。

为什么会这样?我应该怎么做才能解决这个问题,以便我的箭头键仍然被检测到被按住?

为每个箭头键初始化一个间隔计时器,该计时器在按下箭头键时运行。

释放每个箭头后清除它们的间隔计时器:

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

您的箭头键仍被检测为按住:其keydown事件已触发,而其keyup事件尚未触发。 keyupkeydown仅在发生更改时才触发,但有一个例外:操作系统生成的键盘重复事件。(您可以通过选中e.repeat来过滤掉这些内容。

如果你想要一种简单的方法来查看当前被压制的内容,你必须自己维护该列表:

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

(请注意,keyCode已弃用,如果可能,应使用code

您可以通过使用数组跟踪按下的键并使用计时器监视数组来解决此问题。

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

相关内容

  • 没有找到相关文章

最新更新