Stop propagation with jquery delegate/live function not working

fenderplayer picture fenderplayer · Aug 18, 2010 · Viewed 8.3k times · Source

Heres the problem html:

<ul id="update-list">
<li class="update" onclick="window.location('some_url')">
  <h2> some header </h2>
  <p> some paragraph </p>
  <div>
    <a class="popup-link">
      <span> Show Popup </span>
      <span> + </span>
    </a>
  </div>
</li> 
// this repeats n times
//...
</ul>

When i click on .popup-link link, it should open the lightbox popup only (which it does) but the inline onclick on li also fires. The thing is that the li tags are all part of some partial which is fetched via ajax on different pages. So i use jquery's delegate to bind the events as follows:

$('#update-list').delegate('.popup-link', 'click', function(e){
    // e.target is <span> while e.currentTarget is .popup-link 
    e.stopPropagation();
    //console.log(e.isPropagationStopped());  this shows 'true' in console
    $.popup();   // launch popup
    e.preventDefault(); // or return false
});

This doesn't seem to work and the inline onclick fires anyway. I've tried with live() as well but no success. Is there something i am missing here?

Answer

jAndy picture jAndy · Aug 18, 2010

AFAIK you cannot reliably prevent an inline event handler from firing by stopping the bubbling within an attached event handler.

Furthermore, using live() or .delegate() you cannot use preventDefault() nor stopPropagation(). You need to return false to prevent the bubble phase and the default behavior.

Anyway, as I already mention you can't prevent the inline event handler to fire with that.

So either, create it completely unobtrusive (which is what I highly recommend) or remove that inline click handler in code.

Example:

$('#update-list').delegate('.popup-link', 'click', function(e){       
   $.popup();   // launch popup
   return false;
}).delegate('.update', 'click', function(){
   window.location('some_url');
})
// the rest of this is unnecessary if you can just omit the onclick attribute 
.find('.update')
  .removeAttr('onclick'); 

Ref.: .delegate()