最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How do I capture a keydown event on the canvas without interfering with the rest of my website? - Stack Overflow

programmeradmin2浏览0评论

I am working on a canvas game using a few tutorials and tweaking them for some AI interaction. The game works great except my event listeners are just added to the document at the moment. When I moved the game to my actual website this became an issue because I needed to e.preventDefault to keep the page from scrolling around. Not a big deal until people wanted to type into my contact form and they couldn't use the space bar or arrow keys. Simple enough fix seems to be adding the event listener only to my canvas.

However, when I use canvas.addEventListener() with the same parameters that I was using it before I can't make the canvas pay attention to the events. They don't seem to register at all. I've tried clicking on the canvas to get it "focussed" but that doesn't seem to do anything.

So the question is how can I make the canvas and only the canvas listen to keydown events?

This works but breaks my forms

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

This doesn't work

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

I am working on a canvas game using a few tutorials and tweaking them for some AI interaction. The game works great except my event listeners are just added to the document at the moment. When I moved the game to my actual website this became an issue because I needed to e.preventDefault to keep the page from scrolling around. Not a big deal until people wanted to type into my contact form and they couldn't use the space bar or arrow keys. Simple enough fix seems to be adding the event listener only to my canvas.

However, when I use canvas.addEventListener() with the same parameters that I was using it before I can't make the canvas pay attention to the events. They don't seem to register at all. I've tried clicking on the canvas to get it "focussed" but that doesn't seem to do anything.

So the question is how can I make the canvas and only the canvas listen to keydown events?

This works but breaks my forms

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

This doesn't work

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);
Share Improve this question edited Mar 18, 2015 at 17:14 CaldwellYSR asked Mar 18, 2015 at 17:06 CaldwellYSRCaldwellYSR 3,2066 gold badges34 silver badges51 bronze badges 4
  • Could you provide a sample code of event registering? – Piotr Dajlido Commented Mar 18, 2015 at 17:09
  • Let me know if you need more information? I think I handled what you were asking? The keysDown array gets handled in my main game loop and there's more code on case 32 to start the game. I have put a console.log in the event listener function which doesn't print when I have canvas.add instead of just add – CaldwellYSR Commented Mar 18, 2015 at 17:16
  • Where do you declare keysDown[e.keyCode] array? – Piotr Dajlido Commented Mar 18, 2015 at 17:20
  • Above that by a couple lines. Simply an empty array. On keyup I delete that keycode. That isn't part of the issue since a console.log before that code doesn't fire. – CaldwellYSR Commented Mar 18, 2015 at 17:26
Add a ment  | 

3 Answers 3

Reset to default 4

The way I handle it in my game engine is I place my canvas inside of a div then capture the events from there. Make certain you set the tabindex on the div so that it can be focused.

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>

You should check this other question: addEventListener for keydown on Canvas

The fix was by caching the last focused element, and then asking if it's the canvas, then do something different.

Hope it works!

Important part is to set tabIndex of canvas to 1 ( which is dirty trick to make any element focusable ).

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

Now you can:

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

Please note that Im using keyup - cause it captures also Del, Home, End, Ins... buttons, keydown captures only Ins from those. keypress is meant to capture only printable keys. So chose whatever suits your needs.

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论