Reputation: 1876
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?
Upvotes: 5
Views: 2840
Reputation: 11
Clone the control and add the clone immediately after the intended one and assign the event, then remove the control:
if ($.browser.msie && (parseInt($.browser.version, 10) == 8 || parseInt($.browser.version, 10) == 7)) {
var btn2 = $(btn).clone();
$(btn).after(btn2);
$(btn).remove();
$(btn2).bind("click", function () {
//your function here
});
}
Upvotes: 1
Reputation: 98
I hate to raise this question from the dead but jquery finally fixed this bug in version 1.7 which was recently released.
Upvotes: 2
Reputation: 950
We actually solve the problem another way, since this is specific to IE, ASP.NET and select element, we use the following code:
$(function () {
if ($.browser.msie) {
var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoaded(function() {
$('select[onchange]:not(.iefixed)')
.addClass('iefixed')
.each(function () {
var self = $(this), dd = self[0], action = self.attr('onchange');
self.removeAttr('onchange').change(action);
dd.onpropertychange = function() { dd.blur(); };
});
});
}
});
Upvotes: 0
Reputation: 344567
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.
Upvotes: 1
Reputation: 65264
something like this?
jQuery(".myDropDown").removeAttr('onchange').change(function() {
alert(0);
});
Upvotes: 0