In my experience, it is rare to assign only a change event to a text input, as any callback that would be executed for the change event should also be called on a key event as well, but with a slight delay (think how an autocomplete shows results as you type). This is a common pattern and I was surprised to not immediately find a jQuery plugin implementing it, so I decided to add one myself.
The jQuery plugin is available at http://plugins.jquery.com/changeOrDelayedKeyListener/.
See the Pen jQuery on Change or Delayed Key Event Listener by Matt Snider (@mattsnider) on CodePen.
The changeOrDelayedKey function has two signatures (this is common with jQuery functions). The first signature is a required callback function, an optional integer in milliseconds to delay before firing the callback on key events, and an optional string name of the key event to target. By default the key delay is 500 milliseconds and the keydown event is used. The second signature has an object, followed by the callback function, and then both optional arguments. And like most jQuery functions, changeOrDelayedKey is chainable.
Looking under the hood, the implementation is fairly simple. The changeOrDelayedKey function first figures out which signature was sent, assigning the correct values to local variables, and sets any defaults. There are two inner functions, the fnExecCallback simply clears any existing timeout and calls the original callback function, while fnDelayCallback waits the delay time before calling fnExecCallback. Some implementations my avoid the extra fnExecCallback, but I want to make sure that the internal timeout is always cleared before delegating to the provided callback functions. Lastly, the fnExecCallback function is assigned to the change event and the fnDelayCallback function is assigned to the desired key event.
There are two caveat when using the changeOrDelayedKey function.
The first is that it doesn’t work well with the jQuery event off function for unsubscribing from events. You can use the off function to remove all change and keydown events, but you can’t remove just the callback function that you provided, because the actual callback function passed into change and keydown listeners is an anonymous function. I don’t foresee a big demand for this feature, so I haven’t included it.
The second is that I haven’t wired it into the jQuery event on function. The signature for the on function adds more complexity that I did not want to support unless absolutely necessary. And since listeners can be called directly, I don’t see a need yet for supporting the on function.