How to Stop Event Bubbling on Checkbox Click

How to stop event bubbling on checkbox click

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

Why does event.stopPropagation() not prevent a label from checking its checkbox on clicks from children elements?

This is not very well specified and is actually platform specific (even though all major platforms/vendors combinations seem to act similarly here). specs - temp link

what [the label element's] activation behavior might be, if anything, should match the platform's label behavior

The de-facto default behavior of the label is to dispatch the click to its linked <input> element ("labeled control"), probably from the legacy-pre-activation behavior, which is triggered before the event is actually dispatched through its path (step 12 here, temp-link).

So even if the event's propagation is stopped at the document's layer in capture phase (first target in the DOM), the default behavior of triggering a new click event on the <input> will happen:

let block_at_capture = false;
const span = document.querySelector("span");
const label = document.querySelector("label");
const input = document.querySelector("input");

span.onclick = (evt) => {
console.log("clicked the span");
};

input.onclick = (evt) => {
console.log("clicked the input");
};

label.addEventListener( "click", (evt) => {
console.log("clicked the label in capturing phase");
}, true );

label.addEventListener( "click", (evt) => {
console.log("clicked the label in bubbling phase");
}, false );

document.addEventListener( "click", (evt) => {
if( evt.target !== span ) { return; }
if( block_at_capture ) {
console.log("blocking at document capture");
evt.stopPropagation();
}
block_at_capture = !block_at_capture;
}, true );
<input id="inp" type="checkbox">
<label for="inp"><span>click me</span></label>

In Angular, how to stopPropagation() of TR click event when checkbox has change event?

The Answer

I was wrong to assume that it being a Bootstrap 4 custom checkbox was immaterial -- in fact that was the key to my problem. In this usage of Bootstrap 4, the <input> itself is invisible! The thing you see on screen that looks like a checkbox is actually generated by CSS. So the click event wouldn't belong to that <input> element in the first place.

To solve the problem, I moved (click)="$event.stopPropagation();" to the <div> element that wraps the custom checkbox, like so:

<tr *ngFor="let t of things" (click)="quack()">
...
<div class="custom-control custom-checkbox" (click)="$event.stopPropagation();">
<input type="checkbox" class="custom-control-input" id="cb{{t.id}}" name="cb1"
[my-directive]="b.somedata">
<label class="custom-control-label" for="cb{{t.id}}"> </label>
</div>
...
</tr>

If I were using normal checkboxes instead of these Bootstrap 4 custom ones, either of the solutions mentioned by ConnorsFan would have worked perfectly.

how prevent the parent click event on change a checkbox

You have to bind the click event on the checkbox and not the change event: http://jsfiddle.net/ohc8jt6w/

Prevent event bubbling in Material UI when Select Dropdown when clicking away

Hmm my best guess is that, the Select component is forwarding the click event from the backdrop to the Select component when you click outside the select.

Since you only catch the blur event, also catching the click event should do the trick.

https://codesandbox.io/s/thirsty-dream-iy3d2?file=/src/App.js

Checkbox change event bubbles up to parent li element while using e.stopPropagation()

EDIT: if you trigger the click event only on the text (which is all you need according to your example) it works:

const checkbox = document.querySelector(".checkboxContainer input");const span = document.querySelector('.edit');
checkbox.addEventListener("change", e => { console.log("only blue fade out")});
span.addEventListener("click", e => { console.log("change text")});
<li>   <label class="checkboxContainer"> <input type="checkbox"> <span class="checkmark"></span>  </label>  <span class="edit">Lorem ipsum</span></li>

React - I can't stop propagation of a label click within a table

The label doesn't have a click handler of it's own, and can't stop propagation, so when you click the label normal event bubbling takes place. This means that all the parent's event handlers are invoked in the correct order. In addition, because of the htmlFor, the checkbox click handler is also triggered, but not as part of the event bubbling.

To solve the problem, add a separate click handler to the label that only includes .stopPropgation() (demo):

var Hello = React.createClass({
func1(e){
console.log('tr was clicked')
},
func2(e){
console.log('td was clicked')
},
func3(e){
e.stopPropagation();
console.log('Checkbox was clicked')
},
stopLabelPropagation(e) {
e.stopPropagation();
},
render: function() {
return <table>
<tbody>
<tr onClick={this.func1}>
<td onClick={this.func2}>
<input id="thing" type="checkbox" onClick={this.func3} />
<label htmlFor="thing" onClick={ this.stopLabelPropagation }>label for checkbox</label>
</td>
</tr>
</tbody>
</table>;
}
});

ReactDOM.render(
<Hello name="World" />,
document.getElementById('container')
);


Related Topics



Leave a reply



Submit