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
JavaScript Syntax (0, Fn)(Args)
Export JavaScript Data to CSV File Without Server Interaction
Calling JavaScript Function in Iframe
Reading Client Side Text File Using JavaScript
How to Save JSON to Local Text File
Uploading Image to Amazon S3 with HTML, JavaScript & Jquery with Ajax Request (No PHP)
How to Create a Responsive Image That Also Scales Up in Bootstrap 3
HTML Dom: Which Events Do Not Bubble
Angular2:Render a Component Without Its Wrapping Tag
How to Detect Escape Key Press with Pure Js or Jquery
React Hooks - Right Way to Clear Timeouts and Intervals
JavaScript Parser in JavaScript
Method Overloading in JavaScript