如何根据子列数据设置rowspan,实现DOM表格的正确排版
解决DOM生成嵌套数据表格的排版问题
你的问题出在rowspan的计算错误和表格行的结构逻辑混乱上:
- 原代码中Option的rowspan设为
item.details.length,但实际上它应该跨该选项下所有Value的总行数,而不是details的数量 - 生成表格行时,没有正确控制每个单元格的出现时机,导致行结构错乱
修正后的代码
let myData = [ { options: "Option 1", details: [ { type: "Big Letters", value: [{name: "A"}, {name: "B"}, {name: "C"}] }, { type: "Small Letters", value: [{name: "a"}, {name: "b"}, {name: "c"}] } ] }, { options: "Option 2", details: [ { type: "Numbers", value: [{name: 1}, {name: 2}, {name: 3}, {name: 4}, {name: 5}] } ] } ]; let html ="<table border='1'>"; html +=` <tr> <th>Options</th> <th>Types</th> <th>Values</th> </tr>`; myData.forEach((item) => { // 计算当前Option需要跨的总行数:所有details下的value数量之和 const totalOptionRows = item.details.reduce((sum, detail) => sum + detail.value.length, 0); let isFirstOptionRow = true; item.details.forEach((item2) => { const totalTypeRows = item2.value.length; let isFirstTypeRow = true; item2.value.forEach((item3) => { html += "<tr>"; // 仅在当前Option的第一行添加Option单元格 if (isFirstOptionRow) { html += `<td rowspan="${totalOptionRows}">${item.options}</td>`; isFirstOptionRow = false; } // 仅在当前Type的第一行添加Type单元格 if (isFirstTypeRow) { html += `<td rowspan="${totalTypeRows}">${item2.type}</td>`; isFirstTypeRow = false; } // 添加Value单元格 html += `<td>${item3.name}</td>`; html += "</tr>"; }); }); }); html += "</table>"; document.body.innerHTML = html;
关键改动说明
- 正确计算rowspan:
- Option的rowspan是该选项下所有Value的总条数,用
reduce累加每个detail的value.length得到 - Type的rowspan是对应detail下的
value.length,这个是正确的,但要控制只在第一行显示
- Option的rowspan是该选项下所有Value的总条数,用
- 控制单元格显示时机:
- 用
isFirstOptionRow标记,仅在当前Option的第一行生成Option单元格 - 用
isFirstTypeRow标记,仅在当前Type的第一行生成Type单元格
- 用
- 规范行结构:每个Value对应一行,只有该行是Option或Type的第一行时,才生成对应的合并单元格,其余行只生成Value单元格
这样生成的表格就能实现你想要的合并单元格排版效果。
内容的提问来源于stack exchange,提问作者Keyboard Corporation
相关产品推荐
相关产品推荐

