Simplest way to detect keypresses in javascript

43

8

I have an idea for a game in javascript (I'm going to make it with EaselJS) and I'll have to detect keypresses. After looking around on the internet I've seen a lot of suggestions (use window.onkeypress, use jQuery, etc.) but for almost every option there's a counterargument. What do you guys suggest? Using jQuery for this sounds easy enough but I have virtually no experience with that library (and I'm not particulary a veteran at javascript either) so I'd rather avoid it. If jQuery is the best option, can someone give a good example (with explanation would be awesome) of how to do this?

I guess this gets asked a lot but I couldn't find any clear answers. Thanks in advance!

bobismijnnaam

Posted 2013-04-18T17:24:27.463

Reputation: 398

1I'd suggest just listening for the keypress event, or possibly one of it's counterparts (keydown or keyup) – Kevin B – 2013-04-18T17:25:38.203

start here - http://api.jquery.com/keypress/

– Mohammad Adil – 2013-04-18T17:25:42.673

2jQuery is JavaScript; the only difference is that jQuery is a library that abstracts away cross-browser differences, to make it easier (but not necessarily more efficient) to write cross-browser code. – David Thomas – 2013-04-18T17:26:00.877

I suggest this: https://github.com/madrobby/keymaster

– SeinopSys – 2013-04-18T17:28:47.290

Answers

64

With plain Javascript, the simplest is:

document.onkeypress = function (e) {
    e = e || window.event;
    // use e.keyCode
};

But with this, you can only bind one handler for the event.

In addition, you could use the following to be able to potentially bind multiple handlers to the same event:

addEvent(document, "keypress", function (e) {
    e = e || window.event;
    // use e.keyCode
});

function addEvent(element, eventName, callback) {
    if (element.addEventListener) {
        element.addEventListener(eventName, callback, false);
    } else if (element.attachEvent) {
        element.attachEvent("on" + eventName, callback);
    } else {
        element["on" + eventName] = callback;
    }
}

In either case, keyCode isn't consistent across browsers, so there's more to check for and figure out. Notice the e = e || window.event - that's a normal problem with Internet Explorer, putting the event in window.event instead of passing it to the callback.

References:

With jQuery:

$(document).on("keypress", function (e) {
    // use e.which
});

Reference:

Other than jQuery being a "large" library, jQuery really helps with inconsistencies between browsers, especially with window events...and that can't be denied. Hopefully it's obvious that the jQuery code I provided for your example is much more elegant and shorter, yet accomplishes what you want in a consistent way. You should be able to trust that e (the event) and e.which (the key code, for knowing which key was pressed) are accurate. In plain Javascript, it's a little harder to know unless you do everything that the jQuery library internally does.

Note there is a keydown event, that is different than keypress. You can learn more about them here: onKeyPress Vs. onKeyUp and onKeyDown

As for suggesting what to use, I would definitely suggest using jQuery if you're up for learning the framework. At the same time, I would say that you should learn Javascript's syntax, methods, features, and how to interact with the DOM. Once you understand how it works and what's happening, you should be more comfortable working with jQuery. To me, jQuery makes things more consistent and is more concise. In the end, it's Javascript, and wraps the language.

Another example of jQuery being very useful is with AJAX. Browsers are inconsistent with how AJAX requests are handled, so jQuery abstracts that so you don't have to worry.

Here's something that might help decide:

Ian

Posted 2013-04-18T17:24:27.463

Reputation: 39 094

1If you're going for cross-browser compatibility, you might need to touch on attachEvent() as well (and not my down-vote, by the way). – David Thomas – 2013-04-18T17:27:39.887

@DavidThomas Yes, I'm not there yet :) – Ian – 2013-04-18T17:27:50.980

1@DavidThomas I'm not worried about downvotes, I'd rather get the right point across. Is the answer any better? I'd be happy to add/change anything – Ian – 2013-04-18T17:43:33.437

It certainly is, up-voted. :) – David Thomas – 2013-04-18T17:51:45.350

1Looks solid, thanks for the explanation! I think I will go with jQuery, I've been looking into it some more and I guess it'll benefit me anyway if I learn to work with it. – bobismijnnaam – 2013-04-18T18:11:26.120

16

KEYPRESS
(enter key)

Vanilla:

document.addEventListener("keypress", function(event) {
    if (event.keyCode == 13) {
        alert('hi.')
    }
})

Vanilla shorthand:

this.addEventListener('keypress', (event) => {
    if (event.keyCode == 13) {
        alert('hi.')
    }
})

jQuery:

$(this).on('keypress', function(event) {
    if (event.keyCode == 13) {
        alert('hi.')
    }
})

jQuery classical:

$(this).keypress(function(event) {
    if (event.keyCode == 13) {
        alert('hi.')
    }
})

jQuery shorthand:

$(this).keypress((e) => {
    if (e.which == 13) {
        alert('hi.')
    }
})

Even shorter:

$(this).keypress(e=>
    e.which==13?
    alert('hi.'):null
)

demo

Thielicious

Posted 2013-04-18T17:24:27.463

Reputation: 1 913

6

There are a few ways to handle that; Vanilla JavaScript can do it quite nicely:

function code(e) {
    e = e || window.event;
    return(e.keyCode || e.which);
}
window.onload = function(){
    document.onkeypress = function(e){
        var key = code(e);
        // do something with key
    };
};

Or a more structured way of handling it:

(function(d){
    var modern = (d.addEventListener), event = function(obj, evt, fn){
        if(modern) {
            obj.addEventListener(evt, fn, false);
        } else {
            obj.attachEvent("on" + evt, fn);
        }
    }, code = function(e){
        e = e || window.event;
        return(e.keyCode || e.which);
    }, init = function(){
        event(d, "keypress", function(e){
            var key = code(e);
            // do stuff with key here
        });
    };
    if(modern) {
        d.addEventListener("DOMContentLoaded", init, false);
    } else {
        d.attachEvent("onreadystatechange", function(){
            if(d.readyState === "complete") {
                init();
            }
        });
    }
})(document);

faino

Posted 2013-04-18T17:24:27.463

Reputation: 2 700

4

Use event.key and modern JS!

No number codes anymore. You can use "Enter", "ArrowLeft", "r", or any key name directly, making your code far more readable.

document.addEventListener("keypress", function onEvent(event) {
    if (event.key === "ArrowLeft") {
        // Move Left
    }
    else if (event.key === "Enter") {
        // Open Menu...
    }
});

Mozilla Docs

Supported Browsers

Gibolt

Posted 2013-04-18T17:24:27.463

Reputation: 4 713