使用jquery从HTML表中提取数据

时间:2013-04-24 00:34:21

标签: javascript jquery html jsp

我正在尝试使用生成的表并使用jquery从中创建一个对象。我看过up examples,但在尝试实施时却出现了一些奇怪的行为。鉴于我的表的这个简化版本(通过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()
    };
});

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

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

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

谢谢!

2 个答案:

答案 0 :(得分:3)

你是input是正确的问题,你必须得到input里面的td的值,.text()未被定义为文本节点,但是它自己的元素,因此你必须在jQuery选择器中指定子元素。另外.val()不适用于输入元素,您可以使用$row.find(':nth-child(1) input').val(); 读取其值。

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

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

或使用.eq()

var noticeMap = {};

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

或者使用键/值对进入单个对象:

td

我不太确定为什么原始尝试会返回第3 .text()内的文字。这真的很奇怪。我会修补它。

修改

在我看来,.find()在某种程度上对它返回的内容非常聪明,它似乎意识到调用td并不会在它找到的第一个匹配项上返回任何内容(第一个:first-child因此,它沿着DOM向下移动以查找具有a的下一个元素,该元素与第3个td内的a标记匹配,然后返回该文本{ {1}}标记。当我删除标题周围的a时,.find()再次开始返回"",我认为这是因为在第一个没有返回任何有用内容之后找不到另一个匹配项。

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

答案 1 :(得分: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()
    };
});