5

Let's say I have a scenario where I have a global plugin (or at least a plugin that binds to a wider array of events).

This plugin takes a selector, and binds a live click to it. Something in pseudo-jquery that might look like this:

$.fn.changeSomething = function(){
     $(this).live("change", function(){ alert("yo");});
}

On another page, I have an additional live binding something like this:

$("input[type='checkbox']").live("click", function(){alert("ho");});

Within this scenario, the checkbox would ideally end up being bound to both live events.

What I'm seeing is that the change event fires as it should, and I'm alerted "yo". However, using this live click event, I never trigger it. However, using an explicit click binding, I DO hit it.

The easy workaround is to trigger a click event at the end of the live change handler, but this seems janky to me. Any ideas?

Note that this is using jquery 1.4.2 and only occurs in IE8 (I supposed 6/7 would too, but I haven't tested them).

an example (you'll need jquery-1.4.2.min.js):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<script src="jquery-1.4.2.min.js" type="text/javascript"></script>
<script type="text/javascript">
    $.fn.changeSomething = function(){
        var t = $(this);
        t.live("change", function(){
            alert("yo");
        }); 
    };

    $(document).ready(function(){
    $("input[type='checkbox']").changeSomething();
    $("#special").live("click", function(){
      alert("ho");
    });
    });
</script>
</head>
<body>
<form>
  <input type="checkbox" id="cbx" />
  <input type="checkbox" id="special" />
  </form>
</body>
</html>
ddango
  • 946
  • 1
  • 12
  • 25
  • Can you post the code around the example not working? e.g. is it wrapped in a ready? – Nick Craver Mar 08 '10 at 23:07
  • Sure, see my most recent edit. Pretty simple example, but this is basically the flow. – ddango Mar 08 '10 at 23:20
  • I get both firing here every time, the change fires then the click...what browser are you using that's having issues? – Nick Craver Mar 08 '10 at 23:25
  • 1
    @ddango - If you bind them in reverse order it works fine...very odd, and IE specific. – Nick Craver Mar 08 '10 at 23:46
  • wow. that's really all i can say. I suppose I could make that change, but I don't really know if that makes me feel any better about it. – ddango Mar 08 '10 at 23:49
  • Hey @Nick @ddango - try this: add a handler for both "click" and "change" for $('body'). It doesn't have to do anything; just return true. When I do that, the event handling works (except for the very first click on the "cbx" checkbox) regardless of registration order. – Pointy Mar 09 '10 at 00:11

3 Answers3

5

You know that IE won't fire the "change" event until the checkbox loses focus, right?

edit while I think that's true, the effect from that test page is pretty bizarre. I'm still playing with it. The "live" mechanism confuses me and makes me a little nervous, though I thoroughly understand its value.

I've put the (slightly modified and clarified) test page up: http://gutfullofbeer.net/clicks.html and I'm going to start doing some jQuery debugging

twilight zone: As noted in comments, when I bind a dummy "change" handler to the body element:

$('body').bind('change', function() { return true; });

then things start working normally. I'm sure that @Alex is right, that there's something going on with the way jQuery is trying to fake the bubbling of the "change" event. Still spooky however. The test page is at http://gutfullofbeer.net/clicks-body.html and you can see the weirdness by clicking the "Setup with change handler first", then click the checkboxes and note that the "click" handler on the second one only fires once, then click the "Bind a handler to the body" and watch how the checkboxes behave after that.

Pointy
  • 405,095
  • 59
  • 585
  • 614
1

Try using $.delegate with a common ancestor instead of $.live

The key to remember with live is that the event is not bound to the element you select. It's bound to document and then once the event bubbles to the document, it checks against the selector you passed in on the event target.

The key to learn from that is that in IE - the change event does not naturally bubble, like in most browsers. In IE the event "bubbles" based on a heuristic that works the same in all of the jquery tests as the actual event in other browsers. There is likely something in your other function that is stopping this heuristic from working. So it makes sense that it's IE specific. Not that that's a good thing...

Alex Sexton
  • 10,401
  • 2
  • 29
  • 41
  • Hi Alex! Sometimes I wear a tie. Anyway, this one is pretty weird. What I've found on top of the fact that the behavior changes based on the ordering of handler registration, it also changes if I directly bind a "click" handler to $('body'). That handler runs, but then both the "click" and "change" handlers always run for the "special" checkbox. I'll try "delegate". – Pointy Mar 09 '10 at 00:09
  • correction - I have to bind a "change" event to the body, not "click". – Pointy Mar 09 '10 at 00:17
  • good suggestion, but I've tried using $.delegate instead ($("body").delegate("#special", "click", function(){...});) but this does not resolve the issue. however, note that changing the order still works with delegate as it did with live. – ddango Mar 09 '10 at 00:31
0

You can use the jquery.livequery plugin

$("select[name='majorsList']").livequery("change",function()
{
alert('in');
});
Jonas Heidelberg
  • 4,984
  • 1
  • 27
  • 41
J Bourne
  • 1,409
  • 2
  • 14
  • 33