55

I've got a page with a variable number of <select> elements (which explains why I'm using event delegation here). When the user changes the selected option, I want to hide/show different content areas on the page. Here's the code I have:

$(document).ready(function() { $('#container').change(function(e) { var changed = $(e.target); if (changed.is('select[name="mySelectName"]')) { // Test the selected option and hide/show different content areas. } }); }); 

This works in Firefox and Safari, but in IE the change event doesn't fire. Anyone know why?

1

10 Answers 10

72

The change event does not bubble in IE (See here and here). You cannot use event delegation in tandem with it.

In fact, it is because of this IE bug that jQuery live had to officially exclude change from the list of supported events (FYI the DOM spec states change should bubble).[1]

With respect to your question, you can bind directly to each select:

$('#container select').change(/*...*/) 

If you really want event delegation you might find some success trying what this person did and bind to click in IE only, which does bubble:

$('#container').bind($.browser.msie ? 'click' : 'change', function(event) { /* test event.type and event.target * to capture only select control changes */ }) 

But this browser detection feels really wrong. I'd really try working with the former example (binding directly to the drop downs). Unless you have hundreds of <select> boxes, event delegation wouldn't buy you much here anyway.


[1] Note: jQuery >= 1.4 now simulates a bubbling change event in IE via live()/on().

Sign up to request clarification or add additional context in comments.

3 Comments

This would be one of the cases you can't get away from browser testing since you can't really feature test. However, for a full solution, you'd have to also handle keyup for keyboard navigation
@Juan: some think feature detecting a bubbling event is possible. See perfectionkills.com/…
That's cool, thanks. Overview of the link that is applicable here: The post is about detecting supported events. By checking for a 'change' event on a div, you'll know whether the change event bubbles, since a div doesn't have its own change event.
3

If I recall correctly you will need to call blur() to have jQuery invoke change() on IE machines. Try something like:

$("select[name=mySelectName]").click(function() { $(this).blur(); }); 

2 Comments

Unfortunately, this doesn't do the trick. The event still isn't fired, even when the <select> is blurred.
I don't think blur automatically fires change. however, blur is propagated properly, so a solution might be a delegated blur event which fires the change event (you could even save the old value as data if you want to check if it's changed). This is a hack. Unfortunately the proper solution requires MS to fix old IE versions
3

using jquery 1.4.4 (and i think 1.4.3) seems to be all good now.... the change event works consistently in my limited testing.

1 Comment

I'm using jQuery 1.7. It works for selects which are on the page when it loads, but not for those dynamically added afterwards (I add a new row when you fill in the last existing row). The problem appears to be limited to IE 8 and below.
3

Idea that might help:

$(document).ready(function() { $('#container select[name="mySelectName"]').change(function(e) { var s = $(e.target); if (s.val()=='1') //hide/show something; }); }); 

If you are using AJAX, try live() function:

 $(document).ready(function() { $('#container select[name="mySelectName"]').live('change', function(e) { var s = $(e.target); if (s.val()=='1') //hide/show something; }); }); 

3 Comments

jQuery/live() does not support the change event. See docs.jquery.com/Events/live#typefn
1.4 supports change event for .live, but the event itself is still a mess in IE as far as I can tell.
.live() is deprecated now in 1.7.7.
1

Add this lines to your page head, Sit back and relax! :)

$(document).ready(function(){$('select').bind('onChange',function(){$(this).blur()});}); 

Comments

1

onchange=doAction will work in IE and Firefox, but its not supported in Chrome.

You need to use jQuery's .change event to handle this.

Comments

0

I'm trying to understand why you need to double check the name of the select after receiving an event to it.

Do you by any chance have multiple elements with the same id ?

Did you actually mean to say "#container select" instead of "#container" ?

3 Comments

No. I'm using event delegation because I don't want to attach the event to every single <select> on the page because there's the potential for dozens of them. By attaching it to the container, there's only a single attachment.
And there are other <select> elements on the page that I don't want this event to fire on.
You can add an ID to the select element itself
0

I'm simply building upon the example set by "Crescent Flesh" for a cross-platform solution that will survive even if loading this SELECT inside #container via an AJAX call.

$('#container').bind($.browser.msie ? 'click' : 'change', function(event) { if ((event.type == 'click') || (event.type == 'change')) { if (event.target.toString().indexOf('Select') != -1) { var sWhich = $('#container SELECT').val(); handleSelectionChange(sWhich); } } }); 

Now you simply build the handleSelectionChange() function, renaming it whatever you want.

Comments

0

IE requires change event to be placed inside document ready. This seems to bind the change event to the associated element. Hope it helps.

Comments

-2

:D:D Wow, I was finding solution... Why think so complicated? Simply:
<select onchange="doAction">

2 Comments

Besides the fact that the question is specifically about jQuery's "change" event, the asker is using event delegation.
Sorry, about little theme miss, but maybe it will help to someone who will be finding solution, none of this^ ideas doesn´t worked for me in IE 8 :(

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.