Jquery:第一个选择器给第二个元素而不是第一个元素

时间:2015-02-06 08:51:54

标签: javascript jquery html

我想从任何单元格中选择第一行,所以我只是写了类似的javascript。

  var curcontrol = $("#cellno_111");
    var firsttd= $(curcontrol).parents("table tbody tr:first");
    alert($(firsttd).text());

我的表位于

之下
<table id="idTable_1" border="1px" width="97%" class="tblDragTable" data-numberofrows="2" data-numberofcolumns="2">
    <tbody>
    <tr id="trno_10">
        <td class="tblCell" id="cellno_100">0</td>
        <td class="tblCell" id="cellno_101">0</td>
        </tr>
    <tr id="trno_11" height="1">
        <td class="tblCell" id="cellno_110" width="1">1</td>
        <td class="tblCell selectedCell" id="cellno_111" width="1">1</td>
        </tr>
    </tbody>
</table>

当我使用find()时,它会给我正确的结果

 var curcontrol = $("#cellno_111");
  var firsttd= $(curcontrol).parents("table tbody").find("tr:first");

但我只是想知道为什么上面的代码会返回第二个tr而不是第一个tr

这是我的JSBIN http://jsbin.com/lisozuvade/1/watch?html,js,output

4 个答案:

答案 0 :(得分:3)

您要求#cellno_111的父母,只有tr的父母。

另请注意,:first.first()类似,因为它会过滤到匹配元素集中的第一个元素,它与成为某个东西的第一个子元素无关。如果您想要多个元素,这些元素是第一个孩子,您应该使用:first-child

.parents(table tbody tr:first):在trtable内查询tbody元素的父元素,然后选择第一个

.parents("table tbody").find("tr:first"):查询tbody内的table元素的父元素,然后查找其中的所有tr,然后选择第一个它们

PS:我建议使用closest代替parents作为祖先的首选DOM导航方法;大部分时间它更实用,更容易理解。

答案 1 :(得分:3)

失败的原因是因为使用parents过滤器调用table tbody tr只会匹配直接父TR。另一个TR落在祖先之外,因此:first将匹配它找到的唯一 TR

如果你试试这个,你会看到发生了什么:

alert($(curcontrol).parents('table tbody tr')[0].outerHTML);

返回:

    <tr id="trno_11" height="1">
        <td class="tblCell" id="cellno_110" width="1">1</td>
        <td class="tblCell selectedCell" id="cellno_111" width="1">1</td>
    </tr>

然后试试这个:

alert($(curcontrol).parents('table tbody')[0].outerHTML);

返回:

<tbody>
    <tr id="trno_10">
        <td class="tblCell" id="cellno_100">0</td>
        <td class="tblCell" id="cellno_101">0</td>
    </tr>
    <tr id="trno_11" height="1">
        <td class="tblCell" id="cellno_110" width="1">1</td>
        <td class="tblCell selectedCell" id="cellno_111" width="1">1</td>
    </tr>
</tbody>

JSFiddle: http://jsfiddle.net/TrueBlueAussie/j28g27m1/

因此,您的第一个示例仅查看祖先(一个TR)并返回第一个匹配项。第二个示例进一步查看树,然后在TR中找到所有 tbody,然后选择first

首选的,稍微快一点的方法是使用closest()find()

e.g。

var curcontrol = $("#cellno_111");
var firsttd= $(curcontrol).closest("tbody").find("tr:first");

或更快(因为选择器从右到左评估):

var curcontrol = $("#cellno_111");
var firsttd= $(curcontrol).closest("tbody").find("tr").first();

e.g。 http://jsfiddle.net/TrueBlueAussie/j28g27m1/1/

答案 2 :(得分:1)

实际上,您需要了解每个选择器正在做什么。尝试使用几个console.log,你会看到:

$(curcontrol).parents();

这返回一组元素。在此集合中,只有tr curcontrol td标记的父级。

您确实可以通过添加额外的过滤器来过滤此特定集:

$(curcontrol).parents("table tbody tr:first");

但正如我刚才解释的那样,原始集只包含一个TR,因此返回的第一个实际上是唯一返回的。

您的find()方法不同,您指定了一个特定的(父)元素,并通过find()搜索了子项,这在这种情况下解释了正确的行为。

答案 3 :(得分:1)

如果我没弄错的话,cellno_111的父层次结构是: trno_11 - &gt; tbody - &gt; table

在您的第一个示例中,第一个trcellno_111项找到trno_11而不是trno_10。它没有trno_10父母。

它与find()一起使用的原因是因为您选择tbody,然后搜索tr所拥有的第一个tbody子项。