8

I'm trying to get used to the new proper way of doing things in jQuery but I can't figure out how to do a "live" binding that's as elegant/DRY as the original. Previously, with "live" I believe you could do this, only mentioning the element once:

$("#element_id").live("click",function(){
  //stuff
}).live("mouseover", function(){
  //stuff
}).live("mouseout", function(){
  //stuff
});

Now, with $(document).on it seems I would need to do this:

$(document).on("click","#element_id",function(){
  //stuff
}).on("mouseover","#element_id",function(){
  //stuff
}).on("mouseout","#element_id",function(){
  //stuff
});

This is less concise and repeats the element. Is there an obviously simpler way to achieve this?

joshuahedlund
  • 1,722
  • 2
  • 20
  • 25
  • Why would you need a delegated event for an element with a *unique identifier* (i.e. its ID) anyway? – Mattias Buelens Feb 06 '13 at 22:15
  • @MattiasBuelens that was a simplified example. Specifically I'm trying to set events for table rows that are loaded dynamically via AJAX, so my actual selector I'm trying not to repeat 3 times is "#element_id tr" – joshuahedlund Feb 06 '13 at 22:17
  • possible duplicate of [JQuery .on() method with multiple event handlers to one selector](http://stackoverflow.com/questions/8608145/jquery-on-method-with-multiple-event-handlers-to-one-selector) – j08691 Feb 06 '13 at 22:19
  • Then you should bind to `#element_id` and use `tr` as descendant selector. – Mattias Buelens Feb 06 '13 at 22:19
  • 1
    @j08691 yes, this looks like it may be a duplicate of that. I looked through at least a dozen questions but didn't find that one! – joshuahedlund Feb 06 '13 at 22:22

2 Answers2

22
$(document).on({
    click: function () {},
    mouseover: function () {},
    mouseout: function () {}
}, '#element_id');

Beware of using document; you may want to use a more specific selector. Also I wouldn't necessarily say it's bad practice to have an ID element loaded dynamically, but it looks suspicious.

Explosion Pills
  • 188,624
  • 52
  • 326
  • 405
  • Thanks, my understanding was that if you use a specific selector, it won't apply to dynamically loaded elements, but (document) will? – joshuahedlund Feb 06 '13 at 22:15
  • @joshuahedlund: The 2nd parameter means to "delegate" the event. – gen_Eric Feb 06 '13 at 22:16
  • 1
    @joshuahedlund As long as the dynamically loaded elements are appended within a 'static' container (e.g. a `#container` which is always in the DOM), you can use that container as binding source (instead of the top-level `document`). The selector argument then filters for events triggered by descendant elements inside that container. – Mattias Buelens Feb 06 '13 at 22:17
  • @joshuahedlund in case you have any doubt, the documentation confirms this: http://api.jquery.com/on/ -- see the second usage – Explosion Pills Feb 06 '13 at 22:21
4

I find this approach useful if your callbacks need to share code:

var handler = function ( event ) {

    var $target = $( event.target );

    if ( $target.is( '#element_id' ) ) }

        switch ( event.type ) {
            case 'click':
                // stuff
            break;
            case 'mouseenter':
                // stuff
            break;
            case 'mouseleve':
                // stuff
            break;
        }

    }

};

$( document ).on({
    click: handler,
    mouseenter: handler,
    mouseleave: handler,
});
isherwood
  • 58,414
  • 16
  • 114
  • 157
whitneyit
  • 1,226
  • 8
  • 17