views:

330

answers:

3

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"&gt;
<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>
+4  A: 

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
interesting discovery, but just further makes me think it is a bug introduced in 1.4.x
ddango
Quite possibly! I'm going to post it at the jQuery forum and see if anybody can explain it.
Pointy
+1  A: 

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
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
correction - I have to bind a "change" event to the body, not "click".
Pointy
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
A: 

Hi Folks,

I experienced the same kind of problem with the .live function.

I would like to warmly thank Alex Sexton for providing us a solution working as replacement to the .live function which is also working in IE.

.delegate works indeed.

Bye.

Guillaume