Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to stop event bubbling on checkbox click

I have a checkbox that I want to perform some Ajax action on the click event, however the checkbox is also inside a container with it's own click behaviour that I don't want to run when the checkbox is clicked. This sample illustrates what I want to do:

$(document).ready(function() {
  $('#container').addClass('hidden');
  $('#header').click(function() {
    if ($('#container').hasClass('hidden')) {
      $('#container').removeClass('hidden');
    } else {
      $('#container').addClass('hidden');
    }
  });
  $('#header input[type=checkbox]').click(function(event) {
    // Do something
  });
});
#container.hidden #body {
  display: none;
}
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
<div id="container">
  <div id="header">
    <h1>Title</h1>
    <input type="checkbox" name="test" />
  </div>
  <div id="body">
    <p>Some content</p>
  </div>
</div>

However, I can't figure out how to stop the event bubbling without causing the default click behaviour (checkbox becoming checked/unchecked) to not run.

Both of the following stop the event bubbling but also don't change the checkbox state:

event.preventDefault();
return false;
like image 475
roryf Avatar asked Jul 22 '09 09:07

roryf


People also ask

How do you stop event capture?

If a listener has been added to the capturing phase, rather than the bubbling phase, then you can prevent the event from capturing down to child elements with the same method: event. stopPropagation() . Show activity on this post. You should pass false as the third argument to the function addEventListener().

Does preventDefault stop bubbling?

preventDefault() Prevents the browsers default behaviour (such as opening a link), but does not stop the event from bubbling up the DOM.

How do you stop event bubbling in cross browser?

In most other browsers, such as Firefox, Opera, Google Chrome, etc., call the event. stopPropagation() method. You can cancel bubbling in a cross-browser fashion by using the cancelBubble() function, which is used in the following demo. Demo: click any cell in the table and watch the click event bubbling!


9 Answers

replace

event.preventDefault();
return false;

with

event.stopPropagation();

event.stopPropagation()

Stops the bubbling of an event to parent elements, preventing any parent handlers from being notified of the event.

event.preventDefault()

Prevents the browser from executing the default action. Use the method isDefaultPrevented to know whether this method was ever called (on that event object).

like image 89
rahul Avatar answered Oct 03 '22 16:10

rahul


Use the stopPropagation method:

event.stopPropagation();
like image 44
Patrice Neff Avatar answered Oct 03 '22 14:10

Patrice Neff


Don't forget IE:

if (event.stopPropagation) {    // standard
        event.stopPropagation();
    } else {    // IE6-8
        event.cancelBubble = true;
}
like image 38
Faraz Kelhini Avatar answered Oct 03 '22 15:10

Faraz Kelhini


As others have mentioned, try stopPropagation().

And there is a second handler to try: event.cancelBubble = true; It's a IE specific handler, but it is supported in at least FF. Don't really know much about it, as I haven't used it myself, but it might be worth a shot, if all else fails.

like image 41
peirix Avatar answered Oct 03 '22 14:10

peirix


When using jQuery you do not need to call a stop function separate.

You can just return false in the event handler

This will stop the event and cancel bubbling..

Also see event.preventDefault() vs. return false

From the jQuery docs:

These handlers, therefore, may prevent the delegated handler from triggering by calling event.stopPropagation() or returning false.

like image 30
DutchKevv Avatar answered Oct 03 '22 14:10

DutchKevv


This is an excellent example for understanding event bubbling concept. Based on the above answers, the final code will look like as mentioned below. Where the user Clicks on checkbox the event propagation to its parent element 'header' will be stopped using event.stopPropagation();.

$(document).ready(function() {
            $('#container').addClass('hidden');
            $('#header').click(function() {
                if($('#container').hasClass('hidden')) {
                    $('#container').removeClass('hidden');
                } else {
                    $('#container').addClass('hidden');
                }
            });
          $('#header input[type=checkbox]').click(function(event) {
              if (event.stopPropagation) {    // standard
                   event.stopPropagation();
               } else {    // IE6-8
                    event.cancelBubble = true;
               }
          });     
  });
like image 42
mehras Avatar answered Oct 03 '22 15:10

mehras


Credit to @mehras for the code. I just created a snippet to demonstrate it because I thought that would be appreciated and I wanted an excuse to try that feature.

$(document).ready(function() {
  $('#container').addClass('hidden');
  $('#header').click(function() {
    if ($('#container').hasClass('hidden')) {
      $('#container').removeClass('hidden');
    } else {
      $('#container').addClass('hidden');
    }
  });
  $('#header input[type=checkbox]').click(function(event) {
    if (event.stopPropagation) { // standard
      event.stopPropagation();
    } else { // IE6-8
      event.cancelBubble = true;
    }
  });
});
div {
  text-align: center;
  padding: 2em;
  font-size: 1.2em
}

.hidden {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="header"><input type="checkbox" />Checkbox won't bubble the event, but this text will.</div>
<div id="container">click() bubbled up!</div>
like image 25
user2503764 Avatar answered Oct 03 '22 15:10

user2503764


Here's a trick that worked for me:

handleClick = e => {
    if (e.target === e.currentTarget) {
        // do something
    } else {
        // do something else
    }
}

Explanation: I attached handleClick to a backdrop of a modal window, but it also fired on every click inside of a modal window (because it was IN the backdrop div). So I added the condition (e.target === e.currentTarget), which is only fulfilled when a backdrop is clicked.

like image 24
MarcinOstaszewski Avatar answered Oct 03 '22 14:10

MarcinOstaszewski


In angularjs this should works:

event.preventDefault(); 
event.stopPropagation();
like image 34
Kugan Kumar Avatar answered Oct 03 '22 14:10

Kugan Kumar