7

I have a partial view which is returned via an Ajax call with a dataType of html - inside this html is an anchor tag with an id, which I am wiring up a click event using jQuery's .on() API and version 1.7.1 of the framework.

For brevity's sake, imagine the partial view is as follows:

<div id="container" class="modal-dialog">
    <h1>Heading</h1>
    <a id="thelink" href="#">
        <img src="<%:Url.Content("~/Path/To/Image.jpg")%>" /></a>
</div>

..and via a standard $.ajax POST to an MVC controller action which returns the above as a partial view result, which I intercept and spit into the modal dialog.

The event code that I'm attempting to hook up looks as follows:

$(function () {
    $("#thelink").on("click", function (e) {
        e.preventDefault();
        $("#jquery-ui-dialog-box").dialog("close");
    });
});

Now, if I switch the on() to live() - everything works as expected. With the code above though in IE8 (IE8 Standards mode) the event does not fire - breakpoints are not hit, the jQuery UI modal doesn't close as per the example above. With a live() call though, it all works as expected.

This is the first and only time I've ever seen a differential between the behaviour of on() and the deprecated or 'rolled up' event binding API (delegate, live, bind)

I have no issues with reverting to using live() or delegate() but would like to understand why this is occurring, if that is possible!

Regards SB

SpaceBison
  • 3,704
  • 1
  • 30
  • 44

1 Answers1

9

$(foo).live(type, handler) is equivalent to $(document).on(type, foo, handler), so try the following instead;

$(function () {
    $(document).on("click", '#thelink', function (e) {
        e.preventDefault();
        $("#jquery-ui-dialog-box").dialog("close");
    });
});

The signature of live() is confusing; you're not actually binding a handler to the selected elements, but to the document element, which listens for an event to be fired on an element which matches the given selector ( How does jQuery .live() work? ).

$(foo).live(type, handler) is equivalent to $(document).delegate(foo, type, handler);

For future reference, $(foo).delegate(selector, type, handler) can be converted to on() just by swapping the first and second parameters; on() expects the event type first, then the (optional) selector.

Community
  • 1
  • 1
Matt
  • 74,352
  • 26
  • 153
  • 180
  • +1 - perfect - I blindly assumed (wrongly) that the 'signature' of the event wire-up would be the same, but it isn't. Integrating your suggestion works for my actual code. Cheers. – SpaceBison Jan 06 '12 at 11:08
  • @Matt If application has many screens and navigations, and we bind many click handler to $(document), the performance could be impacted. isn't it? – Samba Sep 12 '12 at 12:00
  • @Samba: Whilst correct, you're talking about many, *many*, ***many*** before you notice any performance degradation. Don't forget you can use `delegate()` or `on()` to attach to elements closer to the target element, rather than attaching to `document`. – Matt Sep 12 '12 at 13:20
  • @Matt Thanks for reply. But the problem with $(container).on approach is that - if the container is added to DOM dynamically by Ajax response, it doesn't work, so forced to use document. – Samba Sep 12 '12 at 13:59
  • @Matt It will be great help if you could comment on a approach, I was thinking to do http://stackoverflow.com/questions/12382328/jquery-automatically-attach-or-register-event-handlers-to-user-actions-on-elem – Samba Sep 12 '12 at 14:03