How to stop event bubbling on checkbox click

Viewed 197274

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;
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).

Use the stopPropagation method:

event.stopPropagation();

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.

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.

Related