mootools stop event bubbling when using Event.Delegation (:relay)

1.3k views Asked by At

I am adding events to links that are loaded via ajax. Here is a simplified example of the html:

<div class="ajax-content">
  <div class="parent">
    <a href="#" class="event-link">Click here</a>
  </div>
</div>

All content within ".ajax-content" is loaded via ajax. I don't want the click event for ".event-link" to bubble up to ".parent". If it was not loaded via ajax I could do this:

$$('.event-link').addEvent('click', function(event){
  event.stopPropagation();
  event.preventDefault();
  //do stuff
});

However, I can't figure out how to accomplish the same behavior with (click:relay). This is what I am trying:

$$('.ajax-content').addEvent('click:relay(.event-link)', function(event){
  event.stopPropagation();
  event.preventDefault();
  //do stuff
});

How do I prevent the click event from firing on '.parent'? (I also tried other syntax - event.stop() and returning false, but they had the same results.)

2

There are 2 answers

0
Still don't know everything On BEST ANSWER

I was trying to prevent a delegated click event from firing on div.parent. This can be accomplished in my particular situation by adding a check on the event target in the div.parent event:

$$('.ajax-content').addEvent('click:relay(.event-link)', function(event){
  console.log("hi");
  event.preventDefault();
  //do stuff
});

$$('.ajax-content').addEvent('click:relay(.parent)', function(event) {
  if (event.target.match('a')) return false;
  console.log("parent");
});

Thanks to Dimitar for pointing me in the right direction!

3
Dimitar Christoff On

consider your DOM order and order of event propagation from the top of the DOM tree down:

<div class="ajax-content">
  <div class="parent">
    <a href="#" class="event-link">Click here</a>
  </div>
</div>

you attach the event to div.ajax-content (the delegator). which means, by the time that it hits it, it ALREADY needs to have bubbled through a.event-link, then div.parent and then finally down to div.ajax-content. there is no point in stopping it then, div.parent will come first anyway:

http://jsfiddle.net/dimitar/ChrCq/

here's what happens when you stop the event from the .parent before it reaches the delegator:

http://jsfiddle.net/dimitar/ChrCq/1/

delegation is not w/o it's downsides, i am afraid :)

you may want to also read this recent question / answer that went into some more caveats of delegated events and how they differ from normal events, how to work around the difficulties by alternating delegators. Make (possibly dynamically loaded) element clickable via JavaScript, but give precedence to links contained within - I am still hoping the event delegation in mootools may change somewhat but I just don't see how it will help things in your case.