如何在画布上捕获keydown事件而不干扰我的其他网站?

时间:2015-03-18 17:06:46

标签: javascript html5 canvas addeventlistener

我正在使用一些教程进行画布游戏并调整它们以进行一些人工智能交互。游戏效果很好,除了我的事件监听器刚刚添加到文档中。当我将游戏移动到我的实际网站时,这成为一个问题因为我需要e.preventDefault来防止页面滚动。在人们想要输入我的联系表格并且他们无法使用空格键或箭头键之前,这没什么大不了的。简单的修复似乎只是将事件监听器添加到我的画布。

然而,当我使用canvas.addEventListener()与我使用它的相同参数之前,我无法让画布关注事件。它们似乎根本没有注册。我已经尝试点击画布使其“聚焦”,但似乎没有做任何事情。

所以问题是如何制作画布,只有画布才能听到keydown事件?

这有效但会破坏我的表格

addEventListener('keydown', function(e) {
    keysDown[e.keyCode] = true;
    switch(e.keyCode) {
        case 37: case 38: case 39: case 40:
        case 32: e.preventDefault(); break;
        default: break;
    }
}, false);

这不起作用

var canvas = document.getElementById('world');
canvas.addEventListener('keydown', function(e) {
    keysDown[e.keyCode] = true;
    switch(e.keyCode) {
        case 37: case 38: case 39: case 40:
        case 32: e.preventDefault(); break;
        default: break;
    }
}, false);

3 个答案:

答案 0 :(得分:2)

我处理它的方式in my game engine是我将画布放在div内,然后从那里捕捉事件。确保在tabindex上设置div,以便可以对其进行关注。

var ctx = document.querySelector('canvas').getContext('2d');
ctx.rect(0, 0, 320, 240);
ctx.fillStyle = '#0F0';
ctx.fill();
var container = document.querySelector('div');
container.addEventListener('keypress', function(e) {
  console.log(e);
});
div:focus {
  outline: none;
}
<div tabindex="1">
  <canvas width="320" height="240"></canvas>
</div>

答案 1 :(得分:2)

你应该检查另一个问题: addEventListener for keydown on Canvas

修复是通过缓存最后一个聚焦元素,然后询问它是否是画布,然后做一些不同的事情。

希望它有效!

答案 2 :(得分:0)

重要的部分是将canvas的tabIndex设置为1(这是使任何元素都可聚焦的肮脏技巧)。

const canvasDiv = document.getElementById('my_canvas')
canvasDiv.childNodes[0].tabIndex = '1'

现在您可以:

canvasDiv.addEventListener('keyup', (e) => {
    console.log(e,keyCode)
}, false)

请注意,我使用 keyup -因为它还捕获了Del,Home,End,Ins ...按钮, keydown 仅捕获了其中的Ins。 按键旨在仅捕获可打印的按键。因此,选择适合您需求的任何东西。