如何在不干扰网站其余部分的情况下捕获 canvas 上的按键事件?
How do I capture a keydown event on the canvas without interfering with the rest of my website?
我正在开发一个 canvas 游戏,使用一些教程并调整它们以实现一些 AI 交互。游戏运行良好,除了我的事件侦听器此时刚刚添加到文档中。当我将游戏移至我的实际网站时,这成为了一个问题,因为我需要 e.preventDefault
来防止页面滚动。没什么大不了的,直到人们想输入我的联系表并且他们无法使用 space 栏或箭头键。足够简单的修复似乎只是将事件侦听器添加到我的 canvas.
但是,当我使用 canvas.addEventListener()
时使用的参数与之前使用的相同,我无法让 canvas 关注事件。他们似乎根本没有注册。我试过点击 canvas 来获取它 "focussed" 但这似乎没有任何作用。
所以问题是如何让 canvas 并且只有 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);
这行不通
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);
我处理它的方式 in my game engine 是我将 canvas 放在 div
中,然后从那里捕获事件。确保在 div
上设置 tabindex
以便它可以聚焦。
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>
你应该检查另一个问题:
addEventListener for keydown on Canvas
解决方法是缓存最后一个获得焦点的元素,然后询问它是否是 canvas,然后做一些不同的事情。
希望有用!
重要的部分是将 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。 keypress 旨在仅捕获可打印的键。所以选择适合您的需求。
我正在开发一个 canvas 游戏,使用一些教程并调整它们以实现一些 AI 交互。游戏运行良好,除了我的事件侦听器此时刚刚添加到文档中。当我将游戏移至我的实际网站时,这成为了一个问题,因为我需要 e.preventDefault
来防止页面滚动。没什么大不了的,直到人们想输入我的联系表并且他们无法使用 space 栏或箭头键。足够简单的修复似乎只是将事件侦听器添加到我的 canvas.
但是,当我使用 canvas.addEventListener()
时使用的参数与之前使用的相同,我无法让 canvas 关注事件。他们似乎根本没有注册。我试过点击 canvas 来获取它 "focussed" 但这似乎没有任何作用。
所以问题是如何让 canvas 并且只有 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);
这行不通
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);
我处理它的方式 in my game engine 是我将 canvas 放在 div
中,然后从那里捕获事件。确保在 div
上设置 tabindex
以便它可以聚焦。
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>
你应该检查另一个问题: addEventListener for keydown on Canvas
解决方法是缓存最后一个获得焦点的元素,然后询问它是否是 canvas,然后做一些不同的事情。
希望有用!
重要的部分是将 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。 keypress 旨在仅捕获可打印的键。所以选择适合您的需求。