HTML 5 "input" event support

Intro

The "input" event is a simple event that fires whenever a user-initiated action causes a supported object's value (or state with certain objects) to change.

What "change" means

Change means, "to a *different* value" as in, comparing the value before the user-initiated action is invoked with the value after the user-initiated action is complete to see if the values are not equal.

If normalization (like .replace(/\r\n|\r|\n/g, "\r\n") or .replace(/\r\n|\r/g, "\n") for newlines for example) is done on user input, the comparison should be made after the normalization.

Actions that MUST NOT be considered changes

Actions that are user-initiated

Actions that are not user-initiated

Registering an "input" listener

You can register an "input" listener on any element, document or window object in these ways:

"input" listener on the window object

When you do window.addEventListener("input", function(e){}, false); for example, e.currentTarget should point to e.target.ownerDocument.defaultView and not e.target.ownerDocument.

Objects that fire the "input" event

These are the objects that support firing "input":

The event fires at the object and bubbles all the way up to the object's window.

Here's an example of the firing:

var ev = element.ownerDocument.createEvent("Event");
ev.initEvent("input", true, false);
element.dispatchEvent(ev);

.action property

On the event object that's passed to an "input" listener's callback function, an action property is present. This property will be null except when fired from a contentEditable element or from a document in designMode where it will return a string representing the action that was invoked.

The following are the string values that are to be supported by default. Vendor-specific ones should be prefixed.

.data property

On the event object that's passed to an "input" listener's callback function, a data property is present. This property returns the user input that caused the event to fire.

For example, if the user pasted "zipzambam" into a text field, .data would return "zipzambam". If a user typed the the letter K, .data would retunrn "K".

HTMLInputElement with type="checkbox"

With checkboxes, changing the value of the checkbox doesn't fire "input". Changing the checked state does instead.

.data in this case will return true or false depending if the user checked or unchecked the box.

HTMLInputElement with type="radio"

With radio buttons, when switching between buttons with the same @name, "input" fires with the target being the "switched to" HTMLInputElement.

.data in this case will return null

Value change for contentEditable and designMode

With elements in contentEditable mode and documents in designMode, a change in value happens when the underlying markup that represents the editable content in the field changes.

"beforeinput" event

In addition to firing the "input" event, elements in contentEditable mode and documents in designMode fire "beforeinput".

"beforeinput" works the same way as "input" except that it's cancelable. For example, if a user types a "K" in a text field and doing so will cause a change in the text field's value, "beforeinput" will fire. Then, on the event object passed to the "beforeinput" listener, you can call .preventDefault(), which will cancel the event and prevent the user input from being applied. In this case, if you called .preventDefault(), the "K" would be ignored and not entered.

Also, when you cancel the "beforeinput" event, this causes the "input" event to be canceled (as in, "input" won't fire). This means that "beforeinput" always fires before "input".

Here's an example of the firing:

document.designMode = 'on';
var ev = document.createEvent("Event");
ev.initEvent("beforeinput", true, true);
document.dispatchEvent(ev);

You can register "beforeinput" listeners the same way you register "input" listeners.