Reputation: 148524
The TR has <tr onclick='alert("row");'>
And the button has :
$("body").on('click',".b",function (e){
alert('button');
e.stopPropagation();
});
However - Although I wrote e.stopPropagation();
it still alerts : "row , button".
Now , I know that the event handler is attached to the body
and the selector is checked against it ( the click start at the button and move up to the body , just like $.live
use to do but against document
...).
But the checking should be for the button
click and not for the TR
click.
It seems that while i'm clicking , it propagates to the "body"
( because I attached event handler to it) and while its way up to the body it activates the click on the TR
.
What is going on here? How can I keep my code ( attach to body) and still have only alert of "button".
I know I can simply do :
$(".b").on('click',function (e){
alert('button');
e.stopPropagation();
});
but I want to know why my current(!) code doesnt work.
Upvotes: 23
Views: 67993
Reputation: 425
This is the solution worked properly in my case in Angular using material select
import {Directive, HostListener} from "@angular/core";
@Directive({
selector: "[click-stop-propagation]"
})
export class ClickStopPropagation
{
@HostListener("click", ["$event"])
public onClick(event: any): void
{
event.stopPropagation();
}
}
In template use it like this
(click)="onClick($event)
Upvotes: -1
Reputation: 994
If you want to stop the event propagation from child to parent, then you may use this code.
Let's say you have a select, button, or any other click event inside a div etc. Then Write the below code code on onclick method.
<button type="button" onclick="event.cancelBubble = true;" >Click Me </button>
or
<button type="button" onclick="event.cancelBubble = true; doSomething();" >Click Me </button>
you can replace button with any HTML input or other element.
in your specific case use
<tr onclick='event.cancelBubble = true; alert("row");'>
Upvotes: 2
Reputation: 94101
...but I want to know why my current(!) code doesnt work.
From jQuery docs, on event.stopPropagation
with event delegation:
Since the .live() method handles events once they have propagated to the top of the document, it is not possible to stop propagation of live events. Similarly, events handled by .delegate() will propagate to the elements to which they are delegated; event handlers bound on any elements below it in the DOM tree will already have been executed by the time the delegated event handler is called. These handlers, therefore, may prevent the delegated handler from triggering by calling event.stopPropagation() or returning false.
live
and delegate
are now on
so this applies.
Upvotes: 9
Reputation: 382150
The problem is that you're attaching the event handler to the body
, even if it delegates to the .b
element. This event handler is called only after the tr
event handler is called, so it's too late to stop propagation.
As I suppose you want to deal with dynamically added elements and can't simply bind the event handler to the td
, I can suggest you this :
$('body').on('click',"tr",function (e){
alert('row');
});
$("body").on('click',".b",function (e){
alert('button');
e.stopPropagation();
});
Upvotes: 20