Update: after a long period of inactivity, I didn’t realise there was a minor bug in the code. Couple that with the fact that it didn’t work in newer versions of jQuery, and I decided to remove the code from this page. However, there’s a fork of the code available at https://github.com/dodo/jquery-inputevent, which works with newer jQuery versions.
After posting my first technical blog post, Effectively detecting user input in JavaScript, I felt like I needed to expand on a few things that I didn’t cover. For instance, the fact that input
is a bubbling event and propertychange
is not, or that detecting support for input
is made extra difficult by Firefox. Instead of expanding that article, I decided I would write a snippet to try and normalize the event a little better. I chose jQuery as a base for the code, mostly because I wanted to learn more about writing custom events for jQuery, but partly because I knew it would make a lot of things easier. The result is the input event plug-in below.
I wasn’t really sure where to start, but Googling turned up Ben Alman’s excellent jQuery special events post which tells you more or less everything you need to know. After that, I was able to create a basic plug-in that would provide an interface for jQuery.fn.bind("input")
. The plug-in decides between attaching to input
, propertychange
or a host of fall back events that may or may not be supported in the browser. In short, it tries to get as much of the functionality of input
as possible, but there’ll always be at least some functionality, for instance, plain keyboard input detection.
Note that the plug-in does have the following limitations in browsers that don’t support input
:
- There’s no “catch-all-changes” fallback. I had considered running a timer, when an element is focused or moused over, that constantly checks for value changes. However, this would trigger when the value of the element is changed programmatically, which may not be desired.
- Because IE’s
propertychange
triggers when the value of an element is changed programmatically, that browser suffers from the problem described by the limitation above this one. It is possible that an infinite loop could be caused by always changing the value of the element in the event handler. A workaround, if you need to do this, might be to temporarily unbind whilst you change the value, rebinding after changing. - It currently only works with input and textarea elements. I may be able to get some support in for contentEditable elements in the future, but they don’t fire a
propertychange
event in IE when typing or pasting, which makes them awkward for capturing input. Firefox, Opera and IE9 don’t support the event on contentEditable elements anyway. It will not work withEvent delegation works as of version 1.1live()
ordelegate()
. This is due to how thepropertychange
event doesn’t bubble.It doesn’t work around the bugs Opera has with the input event. I’m not sure which versions are affected and it would be a pain to figure it all out.The plugin should now provide the best level of compatibility possible in all versions of Opera.
Changelog
- v1.1: Oct 24, 2011 — Fixed many browser implementation issues, introduced
live/delegate
compatibility, changed event special name totxtinput
. see full post. - v1.0: Oct 18, 2010 — 1st version
The following fiddle (very basically) demonstrates the event:
[iframe http://jsfiddle.net/AndyE/sdkBs/embedded/result 99% 300px]
Thanks to: Nick Craver, Tim Down, Ben Alman and Daniel Friesen. Please post any issues you come across in the comments.