javascript - 当用户更改选项卡并返回时,停止触发事件监听器

标签 javascript addeventlistener

我正在用 JavaScript 制作一个游戏,其中玩家由箭头键控制。

如果用户按下箭头键并同时更改选项卡,当他们返回选项卡时,由于事件监听器触发 keydown,玩家仍在移动,而没有注意到 keyup 用户更改选项卡后。

在用户切换选项卡并返回后,我如何才能停止触发事件?

换句话说,如何确保用户切换选项卡并返回后,玩家不会根据之前按住的箭头键移动?

这是我为呈现该问题而制作的示例:https://jsfiddle.net/mgh38d1e/

var canvas = document.getElementById('game');
var ctx = canvas.getContext('2d');

var player = {x: 0, y: 0};

function loop() {
  // draw background
	ctx.fillStyle = 'blue';
  ctx.fillRect(0, 0, canvas.width, canvas.height);
  
  // draw player
	ctx.fillStyle = 'lawngreen';
  ctx.fillRect(player.x, player.y, 50, 50);
  
  if(right) player.x += 1;
  
  requestAnimationFrame(loop);
}

loop();

var right = false;

addEventListener('keydown', function(e) {
	if(e.key == 'd')
  	right = true;
});

addEventListener('keyup', function(e) {
	if(e.key == 'd')
  	right = false;
});
<h1>Press D to move right</h1>
<canvas id="game" width="600" height="300"></canvas>

最佳答案

这就是我想到的事情。

function byId(id) {
  return document.getElementById(id)
}

function newEl(tag) {
  return document.createElement(tag)
}

function qsa(sel, par = document) {
  return par.querySelectorAll(sel)
}
window.addEventListener('load', onLoaded, false);

class kbKey {
  constructor(name, keyCode) {
    this.name = name;
    this.keyCode = keyCode;
    return this;
  }
}

var keys = [];

var arrowKeys = [
  [null, new kbKey('^', 38), null],
  [new kbKey('<', 37), new kbKey('V', 40), new kbKey('>', 39), ]
];

var numPad = [
  [new kbKey('7', 103), new kbKey('8', 104), new kbKey('9', 105)],
  [new kbKey('4', 100), new kbKey('5', 101), new kbKey('6', 102)],
  [new kbKey('1', 97), new kbKey('2', 98), new kbKey('3', 99)],
  [new kbKey('>', 39), new kbKey('0', 96), new kbKey('.', 110)]
];

function onLoaded(evt) {
  window.addEventListener('keydown', onkeydown, false);
  window.addEventListener('keyup', onkeyup, false);

  window.addEventListener('focus', onFocus, false);
  window.addEventListener('blur', onBlur, false);

  keys = keys.fill(false);

  drawKeys(numPad);
}

function onkeydown(evt) {
  keys[evt.keyCode] = true;
  //	console.log(evt.key, evt.which);
  updateDisplay();
}

function onkeyup(evt) {
  keys[evt.keyCode] = false;
  updateDisplay();
}

function onBlur(evt) {
  keys = keys.fill(false);
}

function onFocus(evt) {
  updateDisplay();
}

function updateDisplay() {
  let cells = Array.from(qsa('#keyboard td'));

  cells.forEach(
    function(cell, index, collection) {
      if (cell.dataset.code != undefined) {
        if (keys[parseInt(cell.dataset.code)] == true)
          cell.classList.add('active');
        else
          cell.classList.remove('active');
      }
    }
  );
}

function drawKeys(keydata2D) {
  let tbl = byId('keyboard');

  keydata2D.forEach(function(rowArray, rowIndex, rowCollection) {
    let tr = newEl('tr');

    rowArray.forEach(
      function(key, col, keyArray) {
        let td = newEl('td');
        tr.appendChild(td);
        if (key != null) {
          td.textContent = key.name;
          td.dataset.code = key.keyCode;
        }
      }
    );
    tbl.appendChild(tr);
  });
}
td[data-code] {
  border: solid 1px gray;
}

.active {
  background-color: #ffad68;
}
<table id='keyboard'></table>

关于javascript - 当用户更改选项卡并返回时,停止触发事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56213363/

相关文章:

php - php 中的表单 javascript 中的验证

javascript - npm 对等依赖检查

javascript - 过滤数组 JavaScript 的对象

javascript - 如何使用javascript通过一个按钮在两种不同颜色之间切换

javascript - 单行辅助函数上是否可以有或是否有 Javascript addEventListener 多个参数?

javascript - Youtube API onYoutubePlayerReady 和 addEventListener 未被触发

javascript - 上传取消方法未触发

javascript - 错误 : The page has been destroyed and can no longer be used

java - 将自定义事件监听器添加到 java bean 中以用于 setter

javascript - 在 javascript 中捕获事件