I’m trying to do the following, seemingly simple thing.
If a key is pressed that would have typed a character in a text input field, and that keypress is not already handled elsewhere (e.g. no input field had the focus), then focus one particular input field and type the character there.
This is to save users a mouse click in a browser game that requires quick responses, but it could equally well be used in, say, a chat application. If the user accidentally forgot to focus this (big and obvious) input field, then I want to handle this gracefully and not punish them.
Caveats:
- If any input field has focus, the event should go there and nowhere else.
- Keys that do not type characters (Enter, arrow keys, PgUp, PgDn, …) should be left to do their default behaviour.
Using jQuery, I came up with something like this:
$(document).keypress(function(e) {
var input = $("#my-input-field");
if (e.which >= ' ' && !input.is(":focus")) {
input.focus();
input.trigger(e);
e.preventDefault();
}
});
However, this does not work, for two reasons:
- Events still bubble up to
documenteven if a particular input field handles them. Possible solutions:- Hook up
keypressevent handlers to all input fields and callstopPropagationin each, but that sounds like a horrible hack waiting to go wrong. - Check in the above handler whether an input field currently has focus, and ignore it if so, but that sounds like I’d be missing some corner cases where something else is using the keypresses.
- Hook up
- Calling
.trigger(e)does not work. It does call my custom event handlers, but does not trigger the defautkeypressbehaviour of actually inserting the character.
What is the cleanest way out?
Thinking about it, the events fire in this order:
keydown,keyup,keypress.You can use something like:
Then the keydown event will finish, it will later fire the keyup event (on the now-focused field) and should write the character into the field, and then fire the keypress event that other events (if any) tied to the field can use.
The contents of the if statement can be changed to filter out certain key presses, or to add other tags, like
<canvas>to the “do-not-touch” list.Also note that I haven’t tested this, but it theoretically should work. 🙂