When filling out online forms, I love to use my keyword as a means to both provide information as well as to navigate from form field to form field. This works great; but from time to time, an "itchy Tab finger" causes me to accidentally hit "Enter" on an inappropriate form element (such as a Cancel link). Falling victim to this problem the other day, I wondered if there was a way to determine which device - the mouse or the keyboard - triggered the "click" event. If I could, then I thought it might provide an opportunity to confirm an action if, say, a Cancel link were triggered from the keyboard rather than the mouse.
There are two ways for a user to activate a link: either clicking the link directly with the mouse; or, bringing the link into focus and then hitting the Enter key on the keyboard. Both of these actions trigger a "click" event. But, after I looked at the Event object being produced, I couldn't find a consistent, cross-browser way to determine which device initiated the event.
As such, I thought I might try to create a custom jQuery Event Type - "clickwith" - that would piggyback the native click event and include keyboard conditions during the event dispatch.
Before I get into the code, I should warn you that the jQuery custom Event system is a bit of mystery to me. I can get it to, "work." But, I don't necessarily have a great mental model of how it all fits together or how the underlying events are bound and dispatched. And, forget about including data and namespaces in the mix - that's already way beyond my current understanding.
That said, the idea behind this custom event, clickwith, is that we'll bind some key events as well as a click event. The key events - keyup and keydown - will keep track of key activity surrounding the click event. Then, when the custom "clickwith" event is being dispatched, it can use this key-based metadata as part of the outgoing event data.
The pseudo-code for the approach is as follows:
- If key pressed and key is Enter, set flag to True.
- If click event is raised and flag is true, announce keyboard.
- If click event is raised and flag is false, announce mouse.
- If key released, set flag to false.
As you can see, the keyboard events simply set a flag that is used within the click event handler. Ok, let's take a look at the code:
Again, the way the special Events work in jQuery is not something that I have a strong grasp of. As such, I won't try to explain this code too much. If you look at the video above, however, you will see that this is working both for locally-bound events as well as delegated event bindings.
For a very in-depth exploration of jQuery special events, take a look at this article by Ben Alman - his understanding is a world better than mine.
Want to use code from this post? Check out the license.