开发者

Prevent "bubbling"? [duplicate]

This question already has answers here: 开发者_StackOverflow社区 jquery stop child triggering parent event (7 answers) Closed 8 years ago.

I am not sure this is really bubbling, I will explain.

I have this:

<div>
  <div>
    text here
  </div>
</div>

How to bind an on click event so that it will affect only the enclosed div? If I set it like this:

jQuery('div').bind('click', function() {
  jQuery(this).css('background','blue');
});

it makes blue all the divs. If I add false as the third argument(prevent bubbling) to the bind function it does nothing.

How can I solved this?


http://api.jquery.com/event.stopPropagation/

Add event.stopPropagation(); inside the hander.

(It might be better, though, to assign an ID or class to the nested DIV so you can be sure it's the only one affected.)


You should really use identifiers like IDs or classes, but for your example, you could do this:

jQuery('div > div').bind('click', function() {
  jQuery(this).css('background','blue');
});

...which will bind the handler to any div that is a direct descendant of another div.

So either make your initial selection specific to the element(s) you want to affect, or use event delegation, placing a handler on an ancestor, and testing for the element you want.

Delegation example: http://jsbin.com/ehemac/edit#javascript,live

<div id="container">
    <div class="outer">
      <div>
        text here
      </div>
    </div>
    <div class="outer">
      <div>
        text here
      </div>
    </div>
</div>
jQuery('#container').delegate( '.outer > div', 'click', function() {
    jQuery(this).css('background','blue');
});

This uses the delegate()[docs] method that places a handler on the ancestor with the ID #container.

The first argument to .delegate() is a selector. Any elements that are clicked inside #container will have that selector compared against the element clicked. If the selector matches, the handler will be invoked.


http://jsfiddle.net/vol7ron/WzSkj/

Targeting the last descendant


Credit to Patrick DW:

jQuery('div:not(:has(div))').bind('click', function() {
   jQuery(this).css('background','blue');
});

This should be all you need as it will look at all div and find those that don't have child divs (thus, they will be the last descendant of that element type. You could further filter this to make sure they have a parent that is a div, if you wanted to exclude those divs that are standalone.



Older Answer:

This is not by any means meant to be a complete/robust plugin. It serves as only an example of how to target the last element in a chain. See the revision history for a way to do it w/o the plugin. This should be modified if you wish to use it for production.

Plugin:

(function($){
   $.fn.lastDescendant = function(el){
      var found = jQuery(el + ':first').siblings(el).andSelf();
      var prev, curr;
      var stack = this;
      for (var i=0,n=found.length; i<n; i++){
         curr = found.eq(i).find(el);
         while (curr.length){
            prev = curr;
            curr = curr.find(el);
         }         
         stack = stack.add(prev);
      }
      return stack;
   };
})( jQuery );

Example Call:

jQuery.fn.lastDescendant('div')
      .click(function(){
         jQuery(this).css("background","#09c");
      });

Note:

  • this will not select the first (ancestor) element. If you want to select that as well, you could wrap the whole thing in a new div, and then do the above.
  • if I were to make this a production plugin, I would include checking the parameter, and allow you to be able to pass in an object and a starting point (so that siblings are not selected)


To fix this just use a more specific selector

jQuery('div > div').bind('click', function() {
  jQuery(this).css('background','blue');
})


The best way to solve it would be to give your inner div an identifiable feature such as a class, e.g., <div class="inner"></div>.

Alternatively, change your selector:

$('div > div').click(function() {
    $(this).css('background', 'blue');
}


try giving the inner div an id tag and refer to it...

<div><div id=foo>text goes here</div></div>


...

$('#foo').bind('click', function() {
  $(this).css('background','blue');
});

HTH -- Joe

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜