jQuery.在委派时,选择器中只有直接子级

jQuery .on delegation, only direct children in selector

本文关键字:委派 选择器 jQuery      更新时间:2023-09-26

我正试图使用.on将事件绑定到元素的直接子级。

dom看起来是这样的:

table > tbody > tr+ > td > table > tbody > tr+

到目前为止,我已经尝试过:

  • table.find(">tbody").on("dbclick", ">tr", listenerFunction);
  • table.on("dbclick", "> tbody > tr", listenerFunction);

这些都没有按预期工作,并且使用table.on("dbclick", "tr", listenerFunction)会与嵌套表冲突,导致双触发器等,因为这两个表都有这个侦听器。

任何想法都值得赞赏。

<table>
  <tbody>
   <tr><!--Selectable row, adds the row after with sub table --></tr>
    <tr>
      <td>
        <table>
          <tbody>
            <tr></tr>
          </tbody>
        </table>
      </td>
    </tr>
  </tbody>
</table>

在侦听器函数中,使用event.stopPropagation来阻止事件冒泡返回到父tr

function listenerFunc(e) {
    e.stopPropagation();
    // Do your thing...
}

我的建议是向子表添加idclass。这将确保它不会与页面上的任何其他元素或将来发生的任何修改相冲突。假设您将一个类nested-table添加到子表中。代码将如下所示:

$('table.nested-table tr').dblclick(listenerFunc)

正如您所指出的,您引用了表,这应该是有效的:

table.on('dblclick','tr',listenerFunc)

如果您的第一个<table>本身没有嵌套,您可以提供一个选择器,该选择器只匹配不是其他<tr>元素后代的<tr>元素:

table.on("dbclick", "tr:not(tr tr)", listenerFunction);

尝试

var table = $('#tbl')
table.on("click", "> tbody > tr", listenerFunction);
function listenerFunction(e){
    if(!$(this).children().filter($(e.target).closest('td')).length){
        return;
    }
    console.log('direc tr')
}

演示:Fiddle

事实证明,这一部分是我忘记了防止事件冒泡,另一部分是jquery 1.7中的错误/缺失功能。

两个jsfiddles 中的相同代码

  • jQuery 1.7.2
  • jQuery 1.9.1

在jQuery 1.7.2中,将">tr"作为选择器传递给.on是不起作用的,我不知道这是一个bug还是1.7.2中没有实现的东西,但.on方法是在1.7中添加的。

以下代码再现错误。我已经在Mountain Lion上运行的Chrome和在window 7 上运行的Chrome上测试过了

HMTL:

<table id="outer">
    <tbody>
        <tr id="outer-row">
            <td>Hello</td>
            <td>World</td>
        </tr>
        <tr id="outer-row-1">
            <td>
                <table id="inner">
                    <tbody>
                        <tr id="inner-row">
                            <td>nested
                            </td>
                         </tr>
                    </tbody>
                </table>
            </td>
        </tr>
    </tbody>
</table>

JS:

$(function() {
    var handle = function(e) {
        console.dir(this.id);
    };

    $("#outer").children("tbody").on("dblclick", ">tr", handle);
    $("#inner").children("tbody").on("dblclick", ">tr", handle);
});