0

我正在尝试使用 jquery 获取生成的表并从中创建一个对象。我已经查找 示例,但是当我尝试实现时遇到了一些奇怪的行为。鉴于我的表的这个简化版本(通过 Spring MVC 生成):

<table id="notices"> 
  <thead>
    <tr>
      <td class="columnheader">Order</td>
      <td class="columnheader" style="display: none;">ID</td>
      <td class="columnheader">Title</td>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td class="formlabel"><input class="fields" size="2" type="text" value="3"></td>
      <td class="formlabel" style="display: none;">JP-L2913666442781178567X</td>
      <td class="formlabel"><a href="javascript:void(0);" class="editNoticeOpen">*Notice1</a></td>
    </tr>

    <tr>
      <td class="formlabel"><input class="fields" size="2" type="text" value="2"></td>
      <td class="formlabel" style="display: none;">JP-L2913666442760937100X</td>
      <td class="formlabel"><a href="javascript:void(0);" class="editNoticeOpen">Quiz Notice - Formative</a></td>
    </tr>
  </tbody>
</table>

以及我当前脚本的片段:

var noticeMap = $('#notices tbody tr').map(function() {
    var $row = $(this);
    return {
      sequence: $row.find(':nth-child(1)').text(),
      noticeUID: $row.find(':nth-child(2)').text()
    };
});

当我 de[fire]bug 时,noticeMap 看起来像这样:

Object { sequence="*Notice1", noticeUID="JP-L2913666442781178567X"}, 
Object { sequence="Quiz Notice - Formative", noticeUID="JP-L2913666442760937100X"}

不知何故:nth-child(1)正在检索标题,第三个td。我相信这与检索输入的值有关,但我不确定从这里去哪里。可能是因为输入字段在我指定的 td 子项中,所以它不被视为直系后代,所以没有检索到正确的文本?对我来说似乎很奇怪,然后它会跳到第三个 td。唉,我还在用jquery学习,谦虚地请求任何想法和指导。

谢谢!

4

2 回答 2

3

你是对的input,你必须得到inputinside then的值td,它没有被定义为文本节点,而是作为它自己的元素,因此你必须在 jQuery 选择器中指定子元素。也不.text()适用于输入元素,您可以使用.val().

这将有助于您在对象中获得正确的值:

$row.find(':nth-child(1) input').val();

或使用.eq()

var noticeMap = $('#notices tbody tr').map(function() {
    var $cells = $(this).children();
    return {
      sequence: $cells.eq(0).children('input').val(),
      noticeUID: $cells.eq(1).text()
    };
});

或者到具有键/值对的单个对象中:

var noticeMap = {};

$('#notices tbody tr').each(function() {
  var $cells = $(this).children();
  noticeMap[$cells.eq(0).children('input').val()] = $cells.eq(1).text();      
});

我不太确定为什么您最初的尝试会返回 3rd 内的文本td。这真的很奇怪。我会修补一下。

编辑

在我看来,.find()它返回的内容以某种方式很聪明,它似乎意识到调用.text()不会在它找到的第一个匹配项(第一个td)上返回任何内容,因此它沿着 DOM 向下移动以找到下一个确实具有:first-child,它匹配a3rd 内的标签td,然后它返回该a标签的文本。当我删除a标题周围的标题,再次.find()开始返回""时,我认为那是因为在第一个没有返回任何有用的东西之后它找不到另一个匹配项。

在这种情况下使用.children()会更安全,因为它只会找到直接后代并且不会沿着 DOM 向下移动。

于 2013-04-24T00:52:35.737 回答
1

为了获得更好的性能,.eq()请在匹配集上使用:

var noticeMap = $('#notices tbody tr').map(function() {
    var $cells = $(this).children();
    return {
      sequence: $cells.eq(0).find('input').val(),
      noticeUID: $cells.eq(1).text()
    };
});
于 2013-04-24T00:37:30.003 回答