从JavaScript对象创建HTML表格

18

我是JavaScript的初学者,想要在HTML中显示一个对象数组。

数据格式如下:

[
  {"key":"apple","value":1.90},
  {"key":"berry","value":1.7},
  {"key":"banana","value":1.5},
  {"key":"cherry","value":1.2}
]

我想使用一个包含三列(id,name,relevance)的列表来显示它们。并且id可以自动递增。

有谁可以告诉我如何编写javascript代码来显示它?

请给我一些学习材料或示例。


这可能会有所帮助:https://dev59.com/Om445IYBdhLWcg3wTIdf?rq=1 - DevlshOne
你只是想将它打印到一个HTML表格中,是这个意思吗? - SimplGy
你能提供你想要的HTML代码吗?这样会更容易给你一个准确的答案。 - talemyn
可能需要解析JSON(jQuery)$.parseJSON(json..),然后遍历数组的每个元素,并将适当的值附加到适当的位置。 - Kamil
请纠正我如果我错了--->你想解析这个JSON并在你的HTML中显示它吗??这是你想要的吗? - HIRA THAKUR
显示剩余7条评论
9个回答

20

说明

您想使用JavaScript在HTML中填充表格(或其他DOM元素),这是在页面加载时动态执行且收到JSON对象的情况下完成的。

您想要循环处理对象。最好的方法是使用for循环,并确保我们的循环变量对于对象的所有属性(其长度)仍然有效。

获取JSON对象的长度的最佳方法是通过myJSONObject.length :选择myJSONObject的键并返回它们的计数。

您可以在for循环中以以下方式访问存储在JSON对象中的值(假设定义的循环变量命名为i):myJSONObject[i].theAttributeIWantToGet


价格格式化说明

现在,这些价格需要有适当的格式,不是吗? 因此,我们将检查任何value属性是否在其中.之后有少于2个字符。 如果有,我们会添加另一个小数0。 我们还会在编写格式化值之前添加$。 以下是其工作原理的详细说明:

  • obj[i].value.toString().substring(startIndex, length)

    • 我们想检查点之后的长度,因此我们的startIndex将是该字符串中该点的位置。
    • obj[i].value.toString().substring(obj[i].value.toString().indexOf('.'),length)
    • 现在我们需要设置长度。 我们想要找到点之后所有内容的长度,因此为了安全起见,我们将获取整个字符串的长度。
    • 最终结果:obj[i].value.toString().substring(obj[i].value.toString().indexOf('.'), obj[i].value.toString().length) < 2

      • 这将返回true或false。 如果为真:点之后的数字不足2个!
    • 我们添加if语句和最后一个零:

    • if (obj[i].value.toString().substring(obj[i].value.toString().indexOf('.'), obj[i].value.toString().length) < 2) obj[i].value += "0";

另外: 为什么我使用innerHTML而不是appendChild()


解决方案

JSFiddle

HTML

<table>
    <tbody id="tbody"></tbody>
</table>

JSON

[{
    "key": "apple",
    "value": 1.90
}, {
    "key": "berry",
    "value": 1.7
}, {
    "key": "banana",
    "value": 1.5
}, {
    "key": "cherry",
    "value": 1.2
}]

JavaScript

注意: 在这个例子中,JSON对象将被命名为obj

var tbody = document.getElementById('tbody');

for (var i = 0; i < obj.length; i++) {
    var tr = "<tr>";

    /* Verification to add the last decimal 0 */
    if (obj[i].value.toString().substring(obj[i].value.toString().indexOf('.'), obj[i].value.toString().length) < 2) 
        obj[i].value += "0";

    /* Must not forget the $ sign */
    tr += "<td>" + obj[i].key + "</td>" + "<td>$" + obj[i].value.toString() + "</td></tr>";

    /* We add the table row to the table body */
    tbody.innerHTML += tr;
}

JSFiddle


1
"Object.keys(obj).length" <- 这样写有点丑,最好使用 obj.length。 - Dima
@Dima:你说得对。我本以为我可以优化性能,但那是我犯的一个愚蠢错误。我去再拿杯咖啡。 - Jeff Noel
@Stano 这个问题不是关于 CSS 或格式的。我使用长变量名是为了清晰易懂,而不是追求代码压缩性能。不过我理解你的意思。 - Jeff Noel
是的,CSS并不是必要的,只是意味着innerHTML可以移动到循环外面。但你的答案也可以。 - Stano

8

这可以通过一个小而巧妙的过程轻松完成:

<table cellpadding="2" cellspacing="2" border="0" bgcolor="#dfdfdf" width="40%" align="center">
<thead>
    <tr>
        <th>Name</th>
        <th width="20%">Age</th>
        <th width="12%">Status</th>
    </tr>
</thead>
    <tbody id="tableData"></tbody>
</table>
<script type="text/javascript">
    var mainObj = [
        {
            name: "Kapil",
            age:  21,
            status: "Active"
        },
        {
            name: "John",
            age:  28,
            status: "Inactive"
        },
        {
            name: "Deos",
            age:  18,
            status: "Active"
        }
    ];
    var k = '<tbody>'
    for(i = 0;i < mainObj.length; i++){
        k+= '<tr>';
        k+= '<td>' + mainObj[i].name + '</td>';
        k+= '<td>' + mainObj[i].age + '</td>';
        k+= '<td>' + mainObj[i].status + '</td>';
        k+= '</tr>';
    }
    k+='</tbody>';
    document.getElementById('tableData').innerHTML = k;
    </script>

6
你可以像这样做:

你可以这样做:

var table = document.createElement("table");

//Add a header
var header = document.createElement("tr");

var idHeaderCell = document.createElement("th");
var nameHeaderCell = document.createElement("th");
var relevanceHeaderCell = document.createElement("th");

header.appendChild(idHeaderCell);
header.appendChild(nameHeaderCell);
header.appendChild(relevanceHeaderCell);

table.appendChild(header);

//Add the rest of the data to the table
for(var i = 0; i < data.length; i++) {
    var id = (i + 1);
    var name = data[i].key;
    var relevance = data[i].value;

    var tr = document.createElement("tr");

    var idCell = document.createElement("td");
    var nameCell = document.createElement("td");
    var relevanceCell = document.createElement("td");

    idCell.appendChild(document.createTextNode(id));
    nameCell.appendChild(document.createTextNode(name));
    relevanceCell.appendChild(document.createTextNode(relevance));

    tr.appendChild(idCell);
    tr.appendChild(nameCell);
    tr.appendChild(relevanceCell);

    table.appendChild(tr);
}

在处理较大的JSON对象时,我建议您使用innerHTML而不是appendChild(),从性能方面考虑。性能比较 - Jeff Noel
它可以工作,只是您忘记创建tBody元素:http://jsfiddle.net/mjE7R/6/ 当使用innerHTML或jQuery时,tBody标签会隐式创建:http://jsfiddle.net/mjE7R/3/(您可以在页面检查器中检查生成的结构)。因此,在这里应该手动创建tBody(至少为了更好地与jQuery兼容)。 - Stano

4
这里有一个函数,可以从任何集合(对象数组)构建表格。 表格生成器
const data=[
    {
        name: "Kapil",
        age:  21,
        status: "Active"
    },
    {
        name: "John",
        age:  28,
        status: "Inactive"
    },
    {
        name: "Deos",
        age:  18,
        status: "Active",
        testing: 'Gooo!!'
    }
]

const createTable=function(data){
const table = document.createElement("table");
const header = document.createElement("tr");
const keys=Object.keys(data[0])
console.log(keys)
for(const key of keys){
    const th=document.createElement("th");
    th.appendChild(document.createTextNode(key));
    header.appendChild(th);
}
table.appendChild(header);
const len=data.length
for(const row of data) {
    const tr = document.createElement("tr");
    for(const key of keys){
        const td = document.createElement("td");
        const content=row[key] ||''
        td.appendChild(document.createTextNode(content));
        tr.appendChild(td);
        delete row[key]
    }
  /****
  you can omit next cycle if all object have the same structor or if the first element of collection have all fields
  ****/
    for(const key in  row){
        const th=document.createElement("th");
        th.appendChild(document.createTextNode(key))
        keys.push(key)
        header.appendChild(th);
        const td = document.createElement("td");
        const content=row[key] ||''
        td.appendChild(document.createTextNode(content));
        tr.appendChild(td);
    }
    table.appendChild(tr);
}
return table

}


2

这是我的ES6解决方案。我使用reduce操作构建了一个Set,用于存储数组中所有对象的键:

    function arrayToTable(data) {
        const keys = [...data.reduce((all, obj)=>{
            Object.keys(obj).forEach(key => all.add(key));
            return all;
        }, new Set())];

        const header = keys.map(key => `<th>${key}</th>`).join('')
        const tbody = data.map(row => keys.map(key => `<td>${row[key]}</td>`).join('')).map(row => `<tr>${row}</tr>`)

        return `<table>
            <thead><tr>${header}</tr></thead>
            <tbody>${tbody}</body>
        </table>`;
    }

1
稳定的解决方案,对于头部检测也很好。不错! - tkiwi

2

使用Array.map()结合模板字面量可以方便地在Javascript中为大型对象呈现HTML标记,实现可扩展性:

function tableMarkupFromObjectArray(obj) {

  let headers = `
  <th>Index</th>
  ${Object.keys(obj[0]).map((col) =>`
  <th>${col}</th>`
  ).join('')}`

  let content = obj.map((row, idx) => `
<tr>
      <td>${idx}</td>
      ${Object.values(row).map((datum) => `
      <td>${datum}</td>`
    ).join('')}
    </tr>
`).join('')

  let tablemarkup = `
  <table>
    ${headers}
    ${content}
  </table>
  `
  return tablemarkup
}


let myobj =[
  { "name": "apple", "rel": 1.90 },
  { "name": "berry", "rel": 1.7 },
  { "name": "banana", "rel": 1.5 },
  { "name": "cherry", "rel": 1.2 }
]

document.querySelector("#mydiv").innerHTML = tableMarkupFromObjectArray(myobj)

http://jsfiddle.net/4L7c5vad/


1
你可能需要为标题也添加<tr></tr>标签,否则在一些旧浏览器中可能无法正常工作! - Bruno Lobo

1

遍历列表并以此方式检索每个项目的数据(假设您的数据在名为data的变量中):

for (var i = 0; i < data.length; i++) {
  var id = i + 1;
  var name = data[i].key;
  var relevance = data[i].value;
}

然后,在每个循环中对变量进行操作,以任何你想要的方式打印它们。

我不知道如何生成一些HTML代码来在这个循环中显示这些数据。你能给我一些代码示例吗?非常感谢。 :) - Bin Zhu

1
我不是完全确定你在寻求什么。根据你的帖子标题,似乎你正在寻找类似于先前回答中提到的JSON.stringfy,但显然你并不是这样做的。
你是否正在尝试创建一个HTML列表?你能再次尝试解释你的需求吗?我怀疑你正在尝试做的并不复杂,如果你提供更多细节和目的,我们肯定可以帮助你。
我猜你正在尝试通过循环遍历JSON对象来显示HMTL。尝试使用这个纯JavaScript示例:
var fruits = JSON.parse('[{"key":"apple","value":1.90}, {"key":"berry","value":1.7}, {"key":"banana","value":1.5}, {"key":"cherry","value":1.2} ]');

var tbl = document.createElement('table');
var thead = document.createElement("thead");
var tbody = document.createElement("tbody")

var tr_head = document.createElement("tr");

var th_id = document.createElement("th");
var th_name = document.createElement("th");
var th_price = document.createElement("th");

th_id.textContent = "Id";
th_name.textContent = "Name";
th_price.textContent = "Price";

tr_head.appendChild(th_id);
tr_head.appendChild(th_name);
tr_head.appendChild(th_price);

thead.appendChild(tr_head);

for(var i = 0, j = fruits.length; i < j; i++) {
    var tr_body = document.createElement("tr");

    var td_id = document.createElement("td");
    var td_name = document.createElement("td");
    var td_value = document.createElement("td");

    td_id.textContent = i;
    td_name.textContent = fruits[i].key;
    td_value.textContent = fruits[i].value;

    tr_body.appendChild(td_id);
    tr_body.appendChild(td_name);
    tr_body.appendChild(td_value);

    tbody.appendChild(tr_body);
}


tbl.appendChild(thead);
tbl.appendChild(tbody);

 console.log(tbl);

这不是他所问的。感谢您的努力,但您的答案是部分的! - HIRA THAKUR

0

可能是这样的:

function obj2htmltable(obj) {
    var html = '<table>';
    for (var key in obj) {
        var value = obj[key].toString();
        html += '<tr><td>' + key + '</td><td>' + value + '</tr>';
    }
    html += '</table>';
    return html;
}

如果存在嵌套结构(对象内部的对象),obj2htmltable() 可以递归调用自身:
function obj2htmltable(obj) {
    var html = '<table>';
    for (var key in obj) {
        var item = obj[key];
        var value = (typeof(item) === 'object') ? obj2htmltable(item) : item.toString();
        html += '<tr><td>' + key + '</td><td>' + value + '</tr>';
    }
    html += '</table>';
    return html;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接