Skip to content Skip to sidebar Skip to footer

Stop Propagation On Live Elements

I'm having an issue with stopping event propagation. Imagine this scenario:

Solution 1:

Here's a demo

The problem is the event has to climb to the parent to find a handler for <img>. So it has to pass through <td> and fires its handler immediately since it's not a delegated handler.

*click*   ,-----------------> (1) fire direct td handler
  img -> td -> tr -> table  
                       '----> (2) fire delegated img handler
                       X<---- (3) e.stopPropagation() //too late!

One way to prevent the double event is also add <td>'s handler to the table as well. jQuery will then evaluate the two handlers, start with the deepest event and if any of those handlers has e.stopPropagation(), events higher up will not fire.

$('table#test').on('click', 'img.live', function(e){
    e.stopPropagation();
    alert('Image clicked!');            
});

$('table#test').on('click','td.row', function(e){
     alert('Row clicked!');        
});

*click*                
  img -> td -> tr -> table
                       '----> (1) fire delegated img handler
                       X<---- (2) e.stopPropagation()
                       '----> (3) fire delegated td handler //never gets fired

Solution 2:

Maybe I'm wrong, but can't you use event delegation here?

(function(){
    $('#test').on('click', function(e){
        if ( !/img$/i.test((e.target || e.eventSrc).nodeName)){
          alert('row clicked');
        } else {
          alert('image clicked');
        }           

    });
    $('td.row').html('<img src="'+
                     'http://fc03.deviantart.net/fs71/f/2011/'+
                     '161/f/c/nyan_cat_avatar_by_'+
                     'oxoxnaminemayxoxo-d3il6gm.gif" class="live">');
})();​

It saves you the hassle with propagation. Here's a jsfiddle


Post a Comment for "Stop Propagation On Live Elements"