views:

87

answers:

2

There is a bug in jQuery 1.4.2 that makes change event on select-element getting fired twice when using both DOM-event and a jQuery event, and this only on IE7/8. Here is the test code:

<html>

<head>
    <script src="http://code.jquery.com/jquery-1.4.2.js" type="text/javascript"></script>

    <script type="text/javascript">

       jQuery(document).ready(function() {

         jQuery(".myDropDown").change(function() {


         });

       });

    </script>

</head>

<body>
    <select class="myDropDown" onchange="alert('hello');">
          <option>1</option>
          <option>2</option>
          <option>3</option>
          <option>4</option>
        </select>
</body>

</html>

Update: Another view of the problem, actually this is the real problem we have with our application. Binding a live change event on a selector that isn't even touching the select-element with DOM-event also causes double firing.

<html>

<head>
    <script src="http://code.jquery.com/jquery-1.4.2.js" type="text/javascript"></script>

    <script type="text/javascript">

       jQuery(document).ready(function() {

         jQuery(".someSelectThatDoesNotExist").live("change", function() {


         });

       });

    </script>

</head>

<body>
    <select class="myDropDown" onchange="alert('hello');">
          <option>1</option>
          <option>2</option>
          <option>3</option>
          <option>4</option>
        </select>
</body>

</html>

Ticket to actual bug: http://dev.jquery.com/ticket/6593

This causes alot of trouble for us in our application cause we use both ASP.NET-events mixed with jQuery and once you hook up a change event on any element every select (dropdown) gets this double firing problem.

Is there anyone who knows a way around this in the meantime until this issue is fixed?

A: 

something like this?

jQuery(".myDropDown").removeAttr('onchange').change(function() {

 alert(0);
});
Reigel
Then it wouldn't fire at all :)
Nick Craver
ahhh... hmmm... can you please tell me why is that so nick?.... ;) well, I have not tried it though..
Reigel
@Reigel - Sure :) Here's a demo, feel free to try your code: http://jsfiddle.net/jfjBH/ The `onchange` handler is what's firing twice, if you remove it, there's noting to fire. The current bug is he's getting 2 alerts in IE8. As a general rule, don't treat attributes as events (even though they're *declared* that way), they're not *really* related and it only works in IE IIRC.
Nick Craver
okay... thanks nick... I'm digging more on it.. ;)
Reigel
A: 

I had a play around with the bug and there doesn't appear to be any obvious workaround. In my testing I found that the second change event is triggered by jQuery, so I managed to knock together a quick solution that involves removing the DOM 0 event handler and applying it again on a timer that executes immediately when the thread completes:

     jQuery(".myDropDown").change(function() {
         if ($.browser.msie) {
             var dd = $(this)[0], 
                 oc = dd.onchange;
             dd.onchange = null;
             window.setTimeout(function () {
               dd.onchange = oc;
             }, 0);
          }
     });

This works fine for me in IE8, just one "hello" alert appears, although you might want to add an IE check in there. Or not, it probably won't make a difference It definitely needs that check and I've added it to the sample. Here's my fiddle.

The only other solution would be to remove the DOM 0 handler and use the jQuery handler only.

Andy E