onchange vs. oninput for Range Sliders


A common UI pattern for a range slider is to allow the user to move the slider and display the value of it somewhere on the page, changing the displayed value as the user moves the slider.

I think the expected behaviour in such a case is that the value should display instantly, as the user is moving the slider, rather than the page waiting for the slider to finish moving before the displayed value is updated. I suppose there could be cases where you prefer a delay over instant results, but I think the expected behaviour is to display the results instantly.

As you’ll see in the videos below and in your own testing, the behaviour of the input event compared to the change event is not exactly the same in different browsers when applied to a range slider.

Let’s look at how these events behave in the different browsers. The code I’ll be using is embedded in the JS Bin example below:

JS Bin

Swap change with input to see the differences I’ll be discussing. The results described are observed on OSX and Windows 7.

Note: Opera is equivalent to Chrome in these tests because it now has the same rendering engine.

oninput in Chrome

Observations:

  • Works as expected, the input event fires immediately when the slider is adjusted, which is demonstrated by the value changing on the page instantly.
  • Focusing and adjusting the slider with the keyboard has the same result.

onchange in Chrome

Observations:

  • The change event does not fire immediately, demonstrated by the fact that the value on the page does not change until the slider stops moving.
  • Keyboard interaction, however, is the same as oninput, with the value on the page updating immediately.

oninput in Firefox

Observations:

  • Same results as oninput in Chrome; changes happen immediately.
  • Keyboard results the same, changes appear immediately.

onchange in Firefox

Observations:

  • Same results as Chrome; the value doesn’t change on the page until the slider stops moving.
  • When moving the slider with the keyboard, the value does not update until the slider is blurred, or unfocused. This is the only difference from the behaviour in Chrome.

oninput in IE11

Observations:

  • oninput is not recognized at all when used on a range slider. The same event, however, does fire when used on a text input.
  • Although oninput doesn’t fire, the value of the slider is displayed in a native tooltip, which doesn’t happen on the other browsers.
  • The keyboard likewise has no effect on the value and the native tooltip is not displayed.

onchange in IE11

Observations:

  • Works the same way as oninput in Chrome and Firefox; the value changes immediately while the slider is still moving.
  • Keyboard results are the same, the value updates immediately.

What’s the Correct Behaviour?

The WHATWG spec describes the expected behaviour as follows:

The input event fires whenever the user has modified the data of the control. The change event fires when the value is committed, if that makes sense for the control, or else when the control loses focus. In all cases, the input event comes before the corresponding change event (if any).

The same description is found in the W3C version of the spec.

For oninput, Chrome and Firefox have the correct behaviour with both mouse and keyboard interaction. But Firefox seems to have the most accurate behaviour for onchange.

As shown in the quote above, onchange should always fire after oninput, so the fact that Firefox waits for the range slider to lose focus before firing the event (for both mouse and keyboard) seems to be the correct behaviour. Chrome does not wait until the control is unfocused when using the keyboard, but it does so with the mouse.

IE11, of course, is completely wrong on two counts: It doesn’t recognize oninput when applied to a range slider and it responds to onchange as if it was oninput, firing the event immediately instead of waiting until the slider stops moving or loses focus.

As a side point here, the HTML4 spec seemed to define the behaviour a little more clearly:

The onchange event occurs when a control loses the input focus and its value has been modified since gaining focus.

Though when that was written, there was no such thing as type="range" for form inputs.

Sources and Bug Reports

There has been discussion on this behaviour in the bug trackers for the various browsers, and I believe the wording in the spec was updated to be less ambiguous — although I still feel that it’s not 100% clear if Firefox’s keyboard behaviour is the correct one.

Here are some relevant links in addition to the ones provided in the article above:

  • Firefox bug report – Closed as “invalid” since Firefox’s behaviour is correct.
  • IE11 bug report on missing input event, still unresolved.
  • Chrome bug report which I filed myself to see if the different keyboard behaviour can be corrected to agree with Firefox.
  • W3C bug report, which attempts to make the spec less ambiguous.
  • change event on MDN, which explains that “different browsers do not always agree whether a change event should be fired for certain types of interaction.”





Source link

Leave a Reply

Your email address will not be published. Required fields are marked *