none
IE7 input onchange bug

    Question

  •  

    I am writing some Javascript and came across an interesting bug:

    <html>

      <head>  

        <script>

          function changeFocus(){

            document.getElementById("err").innerHTML = " this text is in the div";

          }

        </script>   

      </head>

      <body>

        <div id="err"></div>   

        This is some text on the page<br /><br />

        <input id="i1" type="text" />   

        <input id="i2" type="text" onchange="changeFocus()"/>    

      </body>

    </html>

     

    If you save this to an htm file and view in IE7, start typing in the second input field with the onchange event.  Now click in the first input field and begin typing immediately.  In other words, click in the input field and type simultaneously.  You will begin typing on the page.  Modifying the text on the page instantly.

     

    If you change the onchange event to onblur, this doesn’t happen.  Is this a know issue?

    Thursday, June 12, 2008 7:28 PM

Answers

  • Yes, this is a known bug (or at least it is to many web developers)

    IE has an issue when when:

    onchange event fires, causing DOM structure/content to change (e.g. your .innerHTML change)

    which basically causes a race condition between 2 threads.... the one updating the content (the .innerHTML) and the one moving the focus to the new field.

    Since IE only supports a single GLOBAL event object instead of the W3C Event model where the events are linked to the things that fire them, there are chances for collissions like the one you are witnessing.

    Basically you have 1 event saying "give focus to this" and another saying "change the text content of this"... but they collide, and you end up with focus in the div.

    In all the other Standards based browsers, there is an event instance linked to the "i2" input box, of type "onchange" when you "leave" the input box, by clicking in the "i1" input box, which fires its own linked event for "onfocus".

    The flaw with the MS design is more apparent when you consider the other events (that you are not tracking) that are also firing.

    There is (in rough order, from when you stop typing in "i2"):
    i2Surprisenmousemove, onmouseout  (depending where the mouse was)
    documentSurprisenmousemove
    i1Surprisenmousein, onmouseover, *onhover*, onmousedown
    i2: onchange, onblur
    i1Surprisenfocus, onmouseup, onclick, (onkeydown, onkeyup, onkeypress)


  • For now, your best solution is to either use the onblur... or, try setting the .innerHTML code to fire in a new thread using setTimeout(funcRef,ms)

    Try this, it works AFAIK.

    Code Snippet

    <html>
      <head>
        <script>
          function changeFocus(){
            document.getElementById("err").innerHTML = " This actually works in IE";
          }
        </script>
      </head>
      <body>
        <div id="err"></div>
        This is some text on the page<br/><br/>
        <input id="i1" type="text"/>
        <input id="i2" type="text" onchange="setTimeout(changeFocus,0);"/>
      </body>
    </html>







Friday, June 13, 2008 7:44 PM

All replies

  • Yes, this is a known bug (or at least it is to many web developers)

    IE has an issue when when:

    onchange event fires, causing DOM structure/content to change (e.g. your .innerHTML change)

    which basically causes a race condition between 2 threads.... the one updating the content (the .innerHTML) and the one moving the focus to the new field.

    Since IE only supports a single GLOBAL event object instead of the W3C Event model where the events are linked to the things that fire them, there are chances for collissions like the one you are witnessing.

    Basically you have 1 event saying "give focus to this" and another saying "change the text content of this"... but they collide, and you end up with focus in the div.

    In all the other Standards based browsers, there is an event instance linked to the "i2" input box, of type "onchange" when you "leave" the input box, by clicking in the "i1" input box, which fires its own linked event for "onfocus".

    The flaw with the MS design is more apparent when you consider the other events (that you are not tracking) that are also firing.

    There is (in rough order, from when you stop typing in "i2"):
    i2Surprisenmousemove, onmouseout  (depending where the mouse was)
    documentSurprisenmousemove
    i1Surprisenmousein, onmouseover, *onhover*, onmousedown
    i2: onchange, onblur
    i1Surprisenfocus, onmouseup, onclick, (onkeydown, onkeyup, onkeypress)


  • For now, your best solution is to either use the onblur... or, try setting the .innerHTML code to fire in a new thread using setTimeout(funcRef,ms)

    Try this, it works AFAIK.

    Code Snippet

    <html>
      <head>
        <script>
          function changeFocus(){
            document.getElementById("err").innerHTML = " This actually works in IE";
          }
        </script>
      </head>
      <body>
        <div id="err"></div>
        This is some text on the page<br/><br/>
        <input id="i1" type="text"/>
        <input id="i2" type="text" onchange="setTimeout(changeFocus,0);"/>
      </body>
    </html>







Friday, June 13, 2008 7:44 PM
  • Thanks.  Didn't think of setting the timeout.  How does that solve the issue of collision though of the two threads competing?  And why does onblur work?

     

    Saturday, June 14, 2008 2:33 AM
  • Well, I'm going out on a bit of a limb here, because I can't see the actual source of IE (closed-proprietary, unlike gecko or webkit)

    The "whole" interaction between the onchange event, and the cause (focusing elsewhere) are both running in the "same" context... / "same" time...

    My suspicion is that the global event object ends up relating to 2 seperate elements, in terms of the source/target  source=the 2nd input, target=the 1st input...

    since neither property of the event actaully overrides each other, they happily point to different elements.

    Using the setTimeout(), to do the change, (a) creates another thread, and (b) has no reference to the original (2nd input) element, or the event object at all... thus it "can't fail".

    I'd love for an MSFT employee to give the inside scoop, but I don't see them forthcomming on admitting bugs in IE.  On the IE blog they will only ever confess to "implementing a property/method differently"... they will never come out and say that feature X is broken, it is a bug. Although they will generalize and state that there are some bugs in IE (they conditionalize it with) "as there is in all software"

    Best of luck!

    Monday, June 16, 2008 4:03 PM
  • Just a quick follow up.  Onblur has solved a lot of the problems I was having with Onchange events from a text box.   Hope this has helped other people.
    Friday, November 07, 2008 3:21 PM
  • Hi,

    This code is working fine in my IE7, even I use onchange or onblur event.
    Can you provide me the IE version which you are using.

    Potta Vijay Kumar, Sr. Web Designer / Team Lead
    Tuesday, June 30, 2009 5:58 AM