2015-02-06 173 views
0

我想从任何单元格中选择第一行,所以我只是写了javascript。jquery:第一个选择器给第二个元素,而不是第一个

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

回答

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 s在tbody然后选择first之一。

优选的,稍快,方式是使用closest()find()

例如

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

或更快,但(作为选择进行评估从右到左):

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

例如http://jsfiddle.net/TrueBlueAussie/j28g27m1/1/

+0

完美。这只是返回父母tr ... – 2015-02-06 09:11:06

+0

伟大的***调用父母与表tbody tr的过滤器将只匹配直接父母TR ***,但仍然困惑..为什么'table tbody tr'匹配第一个元素,当我使用'父母()'是'J-query'行为? – 2015-02-06 10:22:09

+0

@Anant Dabhi:在'父母'中,任何选择器纯粹是一个过滤器,应用于父,祖父母,祖父母等的集合。匹配整个选择器的唯一元素是* immediate *父'TR',而不是表中的第一个“TR”。如果你需要更多的解释,请问。 – 2015-02-06 10:24:59

3

你问的#cellno_111父母,只有tr是。

另外请记住,:first就像.first(),因为它会过滤到匹配元素集中的第一个元素,它与作为第一个孩子的东西无关。如果你想要多个元素,这是第一个孩子,你应该使用:first-child

.parents(table tbody tr:first):查询元件的父母要tr其为tabletbody内,则选择第一个

.parents("table tbody").find("tr:first"):查询的元素的父母为tbody其为table内部,然后找到所有tr s在里面,然后选择其中的第一个

PS:我建议使用closest而不是parents作为祖先的前往DOM导航方法;大多数时候它更实用,更易于理解。

+2

这个答案不完整(并且含糊不清)。请提供一个例子,说明他们应该怎么做:) – 2015-02-06 09:00:17

+1

你是否尝试过使用第一个孩子,它不工作... – 2015-02-06 09:01:15

+0

@TrueBlueAussie问题是'但我只想知道为什么上面的代码返回第二个tr而不是第一个tr'回答了这个问题 – 2015-02-06 09:05:55

1

其实,你需要了解每个选择器在做什么。试着用几个console.log,你会看到:

$(curcontrol).parents(); 

这将返回一组元素。在这个集合中,只有1 tr,即您的curcontrol td标签的父级。

你的确可以通过添加额外的过滤器过滤此特定的一组:

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

但正如我刚才解释,原来设置只包含一个单一的TR,所以返回的第一个实际上是唯一一个返回。

您的find()方法是不同的,您指定一个特定的(父)元素和find()您搜索槽儿童,这在这种情况下解释正确的行为。

1

如果我没有记错的cellno_111父层次是: trno_11 - >tbody - >table

在你的第一个例子中,第一trcellno_111认定为trno_11,而不是trno_10。它没有trno_10父项。

它与find()工作的原因,是因为你选择tbody然后搜索第一tr孩子tbody了。

相关问题