嵌套的jQuery选择器如何触发父元素和子元素的特定事件

4
我有一个具有以下结构的表格:
  • table#Main
    • tbody
      • tr.Row
        • td
          • input.EditRow
我的jquery代码如下:
        $("table#Main > tbody > tr.Row").live("click", function (e) {
            RowClick($(this));
        });

        $(".EditRow").live("click", function (e) {
            EditRow($(this));
        });

我的问题是,如果我点击.EditRow按钮并调用EditRow函数,则会立即调用RowClick函数。

在网站上做了一些研究后,我发现其他人通过使用以下任一命令来解决此问题。

e.preventDefault();
e.stopPropagation();

我尝试了不同的组合,但无法弄清楚两个函数的问题。有人能告诉我错在哪里吗?

谢谢!<3


1
您使用的jQuery版本是什么?看起来在这方面有一些变化。如果我加载了 1.4.3 或更高版本,则使用 e.stopPropagation() 对我有效。 示例。 点击链接,您将只收到一个警报。将左侧库切换为使用1.4.2,您将获得两个警报。 - user113716
jquery-1.4.1.js是我Visual Studio 2010版本附带的文件。我现在会下载最新版本... - RoboKozo
1
@Felix:我在评论中更新了一个例子。我也感到非常惊讶。本来想回答,但是觉得最好先测试一下。 - user113716
@Felix:谢谢,但没关系。我已经超过了上限。但是我越想,就有点害怕。我的意思是,似乎jQuery需要测试传递给.live()的每个选择器,以查看调用e.stopPropagation的选择器是否是其子级。这似乎非常低效。编辑:或者也许情况没有那么糟糕。我想它只需要在从e.targetdocument的链中停止传播与.live()选择器匹配的那些元素。谁知道呢。 - user113716
@Felix:我不知道contains()。太好了!我同意有太多.live()监听器是不好的。当然,在我的书中,一个.live()就太多了。;o) - user113716
显示剩余6条评论
2个回答

5

更新: 如@patrick在评论中所示,event.stopPropagation() 应该从 jQuery 1.4.3 开始就可以使用了。


对于 jQuery 1.4.2 及以下版本:

问题在于,由于 .live(),两个事件处理程序都绑定到DOM树的根上:

传递给 .live() 的处理程序从未绑定到一个元素; 相反,.live() 将特殊处理程序绑定到DOM树的根部。

因此,event.stopPropagation 不再起作用(两个事件处理程序位于相同级别):

由于 .live() 方法处理事件时一旦事件已经传播到文档顶部,就无法停止事件传播。

改为使用 event.stopImmediatePropagation 以及颠倒绑定事件处理程序的顺序(否则它将不起作用,因为事件处理程序按照绑定的顺序被调用):

$(".EditRow").live("click", function (e) {
    e.stopImmediatePropagation();
    EditRow($(this));
});

$("table#Main > tbody > tr.Row").live("click", function (e) {
    RowClick($(this));
});

谢谢,Felix Kling!在我更新到最新版本的JQuery之后,这个完美地运行了! - RoboKozo
@Robodude:是的,但我希望你现在正在使用e.stopPropgation(),因为这似乎很好用。无论如何,我将把这个作为其他版本的答案留下来。 - Felix Kling

1
$(".EditRow").live("click", function (e) {
    e.stopPropagation();
    EditRow($(this));
});

应该可以正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接