如何使用jQuery将HTML表转换为Javascript对象

如何使用jQuery将HTML表转换为Javascript对象,javascript,jquery,Javascript,Jquery,我正在尝试转换此HTML表: <table id="students" border="1"> <thead> <tr> <th>Name</th> <th>Age</th> <th>Grade</th> </tr> </thead> &l

我正在尝试转换此HTML表:

<table id="students" border="1">
    <thead>
        <tr>
            <th>Name</th>
            <th>Age</th>
            <th>Grade</th>
        </tr>
    </thead>
    <tbody>
        <tr class="student">
            <td>Oscar</td>
            <td>23</td>
            <td>16.5</td>        
        </tr>
        <tr class="student">
            <td>Antonio</td>
            <td>32</td>
            <td>14</td>        
        </tr>
        <tr class="student">
            <td>Jessica</td>
            <td>21</td>
            <td>19</td>        
        </tr>
    </tbody>
</table>​​​​​​
var tbl = $('table#students tr').map(function() {
  return $(this).find('td').map(function() {
    return $(this).text();
  }).get();
}).get();
["Oscar", "23", "16.5", "Antonio", "32", "14", "Jessica", "21", "19"]
[{id:1, name: "Oscar", age: 23, grade: 16.5}, {id:2, name: "Antonio", age: 32, grade: 14}, {id:3, name: "Jessica", age: 21, grade: 19}]

代码:

<table id="students" border="1">
    <thead>
        <tr>
            <th>Name</th>
            <th>Age</th>
            <th>Grade</th>
        </tr>
    </thead>
    <tbody>
        <tr class="student">
            <td>Oscar</td>
            <td>23</td>
            <td>16.5</td>        
        </tr>
        <tr class="student">
            <td>Antonio</td>
            <td>32</td>
            <td>14</td>        
        </tr>
        <tr class="student">
            <td>Jessica</td>
            <td>21</td>
            <td>19</td>        
        </tr>
    </tbody>
</table>​​​​​​
var tbl = $('table#students tr').map(function() {
  return $(this).find('td').map(function() {
    return $(this).text();
  }).get();
}).get();
["Oscar", "23", "16.5", "Antonio", "32", "14", "Jessica", "21", "19"]
[{id:1, name: "Oscar", age: 23, grade: 16.5}, {id:2, name: "Antonio", age: 32, grade: 14}, {id:3, name: "Jessica", age: 21, grade: 19}]
上述代码将输出以下数组:

<table id="students" border="1">
    <thead>
        <tr>
            <th>Name</th>
            <th>Age</th>
            <th>Grade</th>
        </tr>
    </thead>
    <tbody>
        <tr class="student">
            <td>Oscar</td>
            <td>23</td>
            <td>16.5</td>        
        </tr>
        <tr class="student">
            <td>Antonio</td>
            <td>32</td>
            <td>14</td>        
        </tr>
        <tr class="student">
            <td>Jessica</td>
            <td>21</td>
            <td>19</td>        
        </tr>
    </tbody>
</table>​​​​​​
var tbl = $('table#students tr').map(function() {
  return $(this).find('td').map(function() {
    return $(this).text();
  }).get();
}).get();
["Oscar", "23", "16.5", "Antonio", "32", "14", "Jessica", "21", "19"]
[{id:1, name: "Oscar", age: 23, grade: 16.5}, {id:2, name: "Antonio", age: 32, grade: 14}, {id:3, name: "Jessica", age: 21, grade: 19}]

在这一点上一切都很好,但是如果我希望数组中的javascript对象具有以下结构,我该怎么办:

<table id="students" border="1">
    <thead>
        <tr>
            <th>Name</th>
            <th>Age</th>
            <th>Grade</th>
        </tr>
    </thead>
    <tbody>
        <tr class="student">
            <td>Oscar</td>
            <td>23</td>
            <td>16.5</td>        
        </tr>
        <tr class="student">
            <td>Antonio</td>
            <td>32</td>
            <td>14</td>        
        </tr>
        <tr class="student">
            <td>Jessica</td>
            <td>21</td>
            <td>19</td>        
        </tr>
    </tbody>
</table>​​​​​​
var tbl = $('table#students tr').map(function() {
  return $(this).find('td').map(function() {
    return $(this).text();
  }).get();
}).get();
["Oscar", "23", "16.5", "Antonio", "32", "14", "Jessica", "21", "19"]
[{id:1, name: "Oscar", age: 23, grade: 16.5}, {id:2, name: "Antonio", age: 32, grade: 14}, {id:3, name: "Jessica", age: 21, grade: 19}]

更具体地说…

  • id
    tr
  • 从每行中获取
    姓名
    年龄
    等级

我制作了这个jsfiddle来测试:

<table id="students" border="1">
    <thead>
        <tr>
            <th>Name</th>
            <th>Age</th>
            <th>Grade</th>
        </tr>
    </thead>
    <tbody>
        <tr class="student">
            <td>Oscar</td>
            <td>23</td>
            <td>16.5</td>        
        </tr>
        <tr class="student">
            <td>Antonio</td>
            <td>32</td>
            <td>14</td>        
        </tr>
        <tr class="student">
            <td>Jessica</td>
            <td>21</td>
            <td>19</td>        
        </tr>
    </tbody>
</table>​​​​​​
var tbl = $('table#students tr').map(function() {
  return $(this).find('td').map(function() {
    return $(this).text();
  }).get();
}).get();
["Oscar", "23", "16.5", "Antonio", "32", "14", "Jessica", "21", "19"]
[{id:1, name: "Oscar", age: 23, grade: 16.5}, {id:2, name: "Antonio", age: 32, grade: 14}, {id:3, name: "Jessica", age: 21, grade: 19}]


谢谢

以下功能应该可以正常工作:

var cols = [];
var result = [];
$('#students>thead>th').each(function(){
    cols.push($(this).text().toLowerCase());
});
$('#students>tbody>tr').each(function(id){
    var row = {'id': id+1};
    $(this).find('td').each(function(index){
        row[cols[index]] = $(this).text();
    });
    result.push(row);
});

console.log(result);
基本上,我从表头找到对象属性,接下来我为每一行创建一个对象,将值分配给从前面的数组推导出的属性名称

一些明显的缺陷:

  • 如果表数据由于某种原因而实际不同(例如,示意图中的空行),此系统将在生成的数组中放置空对象
  • 如果在表中使用
    colspan
    属性,此系统不会在不同的对象属性中自动复制相同的值,而是限制设置为剩余的
    s
看到约西亚的方法,它可能比我的更快,因为我的方法试图通过查找财产名称来变得更聪明。如果你确信你的表结构不会改变,我会推荐他的技术。否则,您需要在我的代码行中添加一些内容

哦,为了完整起见,请参见小提琴。额外的数组
map
是不必要的,因为此时您正在为JSON寻找一个文本对象

var data = $('table#students tbody tr').map(function(index) {
    var cols = $(this).find('td');
    return {
        id: index + 1,
        name: cols[0].innerHTML,            // use innerHTML
        age: (cols[1].innerHTML + '') * 1,  // parse int
        grade: (cols[2].innerHTML + '') * 1 // parse int
    };
}).get();

尝试下面的方法,用于n列

演示:

var tblhdr=$('table#students th').map(函数(){
返回$(this.text();
}).get();
控制台日志(tblhdr);
var tbl=$('table#students tbody tr').map(函数(idx,el){
var td=$(el.find('td');
var obj={id:idx+1};
//可以处理列数
对于(变量i=0;i
不知道如果jQuery在这种情况下帮助很大,那么这里有一个简单的JS解决方案,它合理地独立于表结构。它只要求第一行是标题(可以是不同的表节元素,也可以不是),第1+行是数据

该表可以有任意多的列或行,如果其中有rowspan或colspan,则会影响结果(但jQuery也不会帮助您)

它可以很容易地调整为专门使用属性名称的页眉部分,并忽略页脚部分:

function tableToObj(table) {
  var rows = table.rows;
  var propCells = rows[0].cells;
  var propNames = [];
  var results = [];
  var obj, row, cells;

  // Use the first row for the property names
  // Could use a header section but result is the same if
  // there is only one header row
  for (var i=0, iLen=propCells.length; i<iLen; i++) {
    propNames.push(propCells[i].textContent || propCells[i].innerText);
  }

  // Use the rows for data
  // Could use tbody rows here to exclude header & footer
  // but starting from 1 gives required result
  for (var j=1, jLen=rows.length; j<jLen; j++) {
    cells = rows[j].cells;
    obj = {};

    for (var k=0; k<iLen; k++) {
      obj[propNames[k]] = cells[k].textContent || cells[k].innerText;
    }
    results.push(obj)
  }
  return results;
}
函数表toobj(表){
var rows=table.rows;
var propCells=行[0]。单元格;
var propNames=[];
var结果=[];
变量obj,行,单元格;
//使用第一行作为属性名称
//可以使用标题节,但如果
//只有一个标题行

对于(var i=0,iLen=propCells.length;i我需要这个确切的东西,只是我需要更多的功能来覆盖列名并忽略任何隐藏行

例如,您可以这样做:()


需要注意的一点是,id不是结果对象的一部分。您可以从对象的数组位置获取id。或者,如果您确实需要它成为对象的一部分,您可以为id创建一个隐藏列,然后它们将包含在您的小提琴中,您需要的是console.log(数据)而不是console.log(tbl)。第二个例子不是JSON。它是一个JavaScript对象。太多的人已经对JSON是什么感到困惑,所以我要挑明这一点。它很简单,但我必须说我自己需要一些时间才能弄清楚:JSON是一种序列化(“字符串化”)格式。如果不是字符串,则不是JSON;如果是字符串,则可能解析为有效的JSON,也可能解析为无效的JSON。当有人说“JSON对象”时,他们的意思可能是“易于序列化为JSON的数据值”(并非所有值都是如此)。这是否回答了您的问题?当您在表中使用
rowspan
colspan
时,这种方法存在问题。对于普通表,这是完全可以的。@D3V-您是对的,我没有添加任何对
rowspan
colspan
的支持。欢迎您添加支持,我将合并c如果你被绞死了like@lightswitch05:我有一个需要考虑的要求。我在运行时计算了每个属性值的索引,并有一个缓存来存储它们并向前传递这些值,以便所有键都可以与列名正确对齐。我将尝试使该代码更通用,并将其与插件。@D3V json插件的表格已更新,可用于
rowspan
colspan
,它还包括对隐藏列和行的支持()。