12

I've noticed that in different versions of Internet Explorer the onchange event is not captured when the value of an input is altered by a js function, behavior that does not occur with other browsers such as Mozilla or Chrome.

Investigating a little I found that the correct operation of onchange in IE is not guaranteed when the value is altered by js:

function onchangeRequest(){
  console.log('onchange fired');
}

function changeValue (input){
  input.value +=  "hello"
}
<h4> focus lost doesnt invoke onchangeRequest() </h4>

<input id="valueInput"  onkeyup="changeValue(this);" onchange="onchangeRequest();" />

<h4> focus lost invokes onchangeRequest() </h4>

<input id="valueInput" onchange="onchangeRequest();" />

I have not found a convincing explanation of the reasons why IE does not solve those situations correctly. Is this a "known bug" which we have to deal with? Is there any official reference where it is stated that IE does not guarantee the correct behavior of onchange event?

Marcos Martínez
  • 545
  • 2
  • 9
  • 24

1 Answers1

9

I have found that for many years Microsoft followed a strategy whereby it didnt follow the W3C standards in its browser, but the behavior is correct according to IE's own specification:

The onchange event does not fire when the selected option of the select object is changed programmatically.

Reference: MSDN - onchange event

A possible workaround to solve this problem and make your solution cross browser would be:

  • onfocus: save the input value on a expando property
  • onblur: call a js function that compares the old value with the current value.

In my real life scenario i need to fire an ajax action just when the input value changed, so using onblur event without comparing changes would result in a lot of unnecessary calls to the backend.

Here is an example:

function onchangeRequest(input){
  if(input.value != input.oldValue){
      console.log('value changed: do ajax request');
  }else{
      console.log('value didnt change');
  }
}

function changeValue (input){
     input.value +=  "add"
 }
<input id="valueInput" onkeyup="changeValue(this);" onfocus="this.oldValue = this.value;" onblur="onchangeRequest(this);" />
Marcos Martínez
  • 545
  • 2
  • 9
  • 24