1

I'm trying to bind an event for any child within any children in a div except for a specified child with the following:

$(document).ready(function(){

  $("#holder").find('*').each(function(){


    if($(this).context.nodeName !== "SPAN"){
      $(this).click(function(){
        window.console.log('s');
      });
    }
  });

});

However, because the SPAN is within an element, the click event is still being called. Is there any way around this?

I have a demo on JSBin

TheGeekZn
  • 3,516
  • 8
  • 47
  • 87

8 Answers8

2

Add an else condition to negate the click if it is a span

if($(this).context.nodeName !== "SPAN"){
  $(this).click(function(){
    window.console.log('s');
  });
}
else {
  $(this).click(function(e){
    e.stopPropagation(); // negate click
  });
}
techfoobar
  • 63,712
  • 13
  • 108
  • 129
1

You put a click handler on all the p blocks. The span is in one of the p blocks. It gets the click event, but does nothing with it, it then bubbles up to the p.

You need to put a click handler on the span and then have it swallow the event. By calling event.stopPropagation().

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

DrLivingston
  • 768
  • 6
  • 14
1

Try this:

$(document).ready(function(){
  $("#holder").find('*').on('click', function(e){
     if($(e.target).is('span')){
        return;
     }else{
        console.log('s');
     }
  });
});

Demo


Here we are finding all elements in #holder and binding the click event on every node except the span.

Jai
  • 72,925
  • 12
  • 73
  • 99
1

What you encountered is known as Event Bubble. The children's event will be bubbled up to container when it is triggered, To read more about it . Please read What is event bubble?

What is the event.stopPropagation used for?

Hope it is helpful.

Joe.wang
  • 10,945
  • 23
  • 95
  • 175
0

You can check the type of event source and skip the event handler code when event source is span.

Live Demo

$(document).ready(function(){      
  $("#holder *").click(function(event){
    if(event.target.tagName == 'SPAN') return;
    window.console.log('s');
  });      
});
Adil
  • 143,427
  • 25
  • 201
  • 198
0

you can write this code to stop propagating the event to the next level when span is clicked:

$("#holder span").click(function(event,v){
  event.stopPropagation();
});
Alex
  • 447
  • 3
  • 16
0

Can you please try this:

<!DOCTYPE html>
<html>
<head>
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
  <meta charset="utf-8">
<script type="text/javascript">
$(document).ready(function(){

  $("#holder").find('*').each(function(){

    if($(this).context.nodeName != 'SPAN')
    {
      $(this).click(function(e){
        window.console.log('s');
      });
   }
else
{
 $(this).click(function(e){
         e.stopPropagation(); 
      });

}
  });

});
</script>
  <title>JS Bin</title>
</head>
<body>
  <div id="holder">
    <p>some text</p>
    <p>might say</p>
    <p>that being</p>
    <p>in <span annid="1" style="font-weight:bold">space</span></p>
    <p>is like</p>
    <p>communicating with</p>
    <p>dead pixels</p>
  </div>
</body>
</html>

The problem in your code is beacuse of event propagation , the click event is propagating from the <p> event . This is beacuse , the span is inside the <p> element

Hope this helps..

Sai Avinash
  • 4,623
  • 17
  • 55
  • 94
0

You can use:

$("#holder").find("*:not(span)").on('click', function() { ... });
Rotem
  • 2,216
  • 2
  • 23
  • 40