17

我有一个简单的表

在此处输入图像描述

TR 有 <tr onclick='alert("row");'>

按钮有:

$("body").on('click',".b",function (e){
  alert('button');
  e.stopPropagation();
});

但是-尽管我写了 e.stopPropagation();它仍然会发出警报:“行,按钮”。

现在,我知道事件处理程序已附加到body并检查了选择器(单击从按钮开始并向上移动到正文,就像$.live使用做但反对document...)。

但是检查应该是针对button点击而不是针对TR点击。

似乎当我单击时,它会传播到"body"(因为我将事件处理程序附加到它),而当它到达正文时,它会激活对TR.

这里发生了什么?我怎样才能保留我的代码(附加到正文)并且仍然只有“按钮”的警报。

附言

我知道我可以简单地做:

$(".b").on('click',function (e){
  alert('button');
  e.stopPropagation();

});

但我想知道为什么我当前的(!)代码不起作用。

4

5 回答 5

17

问题是您将事件处理程序附加到body,即使它委托给.b元素。此事件处理程序仅在事件处理程序被调用后才tr被调用,因此停止传播为时已晚。

我想你想处理动态添加的元素并且不能简单地将事件处理程序绑定到td,我可以建议你这样做:

$('body').on('click',"tr",function (e){
  alert('row');
});
$("body").on('click',".b",function (e){
  alert('button');
  e.stopPropagation();
});

示范

于 2013-06-10T10:39:12.667 回答
9

...但我想知道为什么我当前的(!)代码不起作用。

从 jQuery 文档开始,event.stopPropagation使用事件委托:

由于 .live() 方法在事件传播到文档顶部后处理事件,因此无法停止实时事件的传播。同样,由 .delegate() 处理的事件将传播到它们被委托的元素;在调用委托的事件处理程序时,绑定在 DOM 树中它下面的任何元素上的事件处理程序将已经被执行。因此,这些处理程序可能会阻止委托处理程序通过调用 event.stopPropagation() 或返回 false 来触发。

live现在delegateon这样。

于 2013-06-10T10:35:27.620 回答
1

如果您想停止从孩子到父母的事件传播,那么您可以使用此代码。

假设您在 div 等中有一个选择、按钮或任何其他点击事件。然后在 onclick 方法上编写以下代码代码。

<button type="button" onclick="event.cancelBubble = true;" >Click Me </button>

或者

<button type="button" onclick="event.cancelBubble = true; doSomething();" >Click Me </button>

您可以用任何 HTML 输入或其他元素替换按钮。

在您的特定情况下使用

<tr onclick='event.cancelBubble = true; alert("row");'>
于 2018-07-23T12:31:39.767 回答
0

我在反应 TS 中的解决方案

event.persist(); 
event.stopPropagation();
于 2019-11-05T12:22:16.797 回答
-1

这是在我使用材料选择的 Angular 中正常工作的解决方案

import {Directive, HostListener} from "@angular/core";

@Directive({
    selector: "[click-stop-propagation]"
})
export class ClickStopPropagation
{
    @HostListener("click", ["$event"])
    public onClick(event: any): void
    {
        event.stopPropagation();
    }
}

在模板中像这样使用它

(click)="onClick($event)
于 2021-09-22T16:43:08.500 回答