Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jquery .live() event interactions

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>
like image 914
ddango Avatar asked Mar 08 '10 23:03

ddango


2 Answers

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.

like image 124
Pointy Avatar answered Oct 03 '22 07:10

Pointy


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...

like image 20
Alex Sexton Avatar answered Oct 03 '22 06:10

Alex Sexton