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
3 Answers
Reset to default 4The 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.