2

这是 HTML:

<table id="tblTestAttributes">
    <thead>
        <tr> <th>Head 1</th> <th>Head 2</th> </tr>
    </thead>
    <tbody>
        <tr> <td id="txtDesc">Item 1</td> <td id="ddlFreq">Assume a DropDownList Here</td> </tr>
        <tr> <td id="txtDesc">Item 1</td> <td id="ddlFreq">Assume a DropDownList Here</td> </tr>
        <tr> <td id="txtDesc">Item 1</td> <td id="ddlFreq">Assume a DropDownList Here</td> </tr>
    </tbody>            
</table>

这是获取每行值的javascript:

var frequencies = [];
if ($('#tblTestAttributes').length) {
    $('#tblTestAttributes tr').each(function () {
        var t = $(this).find('td[id^="txtDesc"]').text() + ";" + $(this).find('[id^="ddlFreq"] option:selected').val();
        alert(t);
        frequencies.push(t);
    });
}

我想避免第一行,其中包含th仅显示标题且不包含任何数据的元素。

所以我将选择器更改为:

#tblTestAttributes tr:not(:first-child)

这也跳过了第二个tr。这里发生了什么?

4

5 回答 5

6

很简单,您可以使用以下代码

$('#tblTestAttributes tr:not(:has(th))').each(function () {
于 2013-07-27T12:15:02.933 回答
3

利用

#tblTestAttributes tr:gt(0)

或者

#tblTestAttributes tbody tr

我会推荐第二个,因为它可以利用 querySelectorAll 并且应该是最快的解决方案。

您的方法没有按预期工作,因为第二个tr也是first-child(of tbody)

于 2013-07-27T12:14:55.907 回答
3

在性能方面,使用.find()会比用 Sizzle 解析选择器要好。

$('#tblTestAttributes').find('tbody').find('tr').each(function () { ... });

这是展示它的jsPerf

于 2013-07-27T12:28:02.100 回答
2

使用tr + tr选择器,它会获取所有tr出现在另一个之后tr的内容,因此会跳过第一个。

也不需要检查表是否存在,因为在这种情况下$.each甚至不会被执行。

var frequencies = [];
    $('#tblTestAttributes tr + tr').each(function () {
        var t = $(this).find('td[id^="txtDesc"]').text() + ";" + $(this).find('[id^="ddlFreq"] option:selected').val();
        alert(t);
        frequencies.push(t);
    });

编辑后:

只需选择所有tr内部tbody

$('#tblTestAttributes tbody tr').each(function(){
    ...
}
于 2013-07-27T12:16:08.200 回答
1

发生这种情况是因为第二行实际上是 的第一个孩子,tbody就像第一行是 的第一个孩子一样thead

为了只取你需要的元素,我建议你需要更接近的东西:

#tblTestAttributes tr:has(td)

不要忘记删除那些重复的txtDescid,这在 HTML 中是非法的,请改用类。

于 2013-07-27T12:16:28.917 回答