DOM event portability revisited

19 July 2011

While my recent game Buzz Grid was very well received, virtually everybody complained about having to use WASD instead of the cursor keys. All my attempts to explain that it was a technical limitation fell on deaf ears. That’s natural; people need solutions, not explanations. But until recently, I couldn’t think of any way to add special key support in a portable manner without either:

Note the portability requirement, which is pretty much the point of making games for Web browsers. And as I explained a while ago, when it comes to the keyboard, only keypress events are portable across all major browsers, and then only for regular keys (letters and digits). Specifically, my event handler looks like this:

window.addEventListener("keypress", function (event) {
    alert(String.fromCharCode(event.charCode || event.keyCode));
}, false);

Now, let’s say you want to add special key handling for just one browser, because one is better than none. How do you go about it? One solution would be to register a second handler that only looks at event.keyCode, but that means code duplication. Another way would be explicitly checking to see which event field is set and do different things, but that’s ugly and wouldn’t really work. Hmm…

Then I realized the expression above will return a character (if an arbitrary one) even for a special key. And it does! Specifically, Firefox returns &, %, ( and ‘ for up, left, down and right respectively. So all I have to do is test for these in addition to W, A, S, D. And to my surprise, it also works on Opera. Which gives me two browser families out of four. Not bad.

The only disadvantage is that the web page will scroll a little every time you press one of the cursor keys. Guess you can’t make an omelet without breaking some eggs. But at least this will be easier to explain. Enjoy!