我使用的是普通表,这是我的要求:
如果表行值重复,则应使用 javascript 合并。例如:表 1 行值和表 2 行值相同,则应合并,并且值应仅使用 javascript 显示一次。在这里我将附上我的代码。
function myFunction() {
const firstRows = { };
let shade = false;
const colsToMerge = [0, 1];
Array.from(document.querySelectorAll('tbody tr')).forEach(tr => {
const text = tr.children[0].innerText;
if (!(text in firstRows)) {
firstRows[text] = { shade, elem: tr, count: 1 };
shade = !shade;
} else {
const firstRow = firstRows[text]
firstRow.count++;
colsToMerge.forEach(i => tr.children[i].remove());
colsToMerge.forEach(i =>
firstRow.elem.children[i]
.setAttribute('rowspan', firstRow.count)
);
}
if (firstRows[text].shade) tr.classList.add('dark');
});
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
th {
background: #a9a9a9;
}
td,
th {
border: 1px solid #dddddd;
text-align: center;
padding: 8px;
font-family: monospace;
font-size: 17px;
}
.dark {
background-color: #dddddd;
}
<body onload="myFunction()">
<table>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tbody>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germanyindgo</td>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
</tr>
<tr>
<td>Island Trading</td>
<td>Helen Bennett</td>
<td>UK</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti</td>
<td>Giovanni Rovelli</td>
<td>Italy</td>
</tr>
</tbody>
</table>
</body>
最佳答案
这是一个有效的解决方案,用于在每一列中动态合并连续的行单元格。
该解决方案还适用于切换阴影,并且只会在“完整”行开始时切换阴影,也就是说,当连续行之间没有合并时。
此外,您必须将表头中的 tr
包装在 thead
中,因为这可能会导致 document.querySelectorAll('tbody tr') 出现问题
事件 tbody
在查询中指定。
function myFunction() {
const previousRow = {};
const colsChanged = {};
let dark = false;
Array.from(document.querySelectorAll('tbody tr')).forEach((tr, rowIdx) => {
Array.from(tr.children).forEach((td, colIdx) => {
if (rowIdx > 0 && previousRow[colIdx].text === td.innerText) {
previousRow[colIdx].elem.setAttribute('rowspan', ++previousRow[colIdx].span);
colsChanged[colIdx] = false;
td.remove();
} else {
previousRow[colIdx] = { span: 1, text: td.innerText, elem: td, dark };
colsChanged[colIdx] = true;
}
});
const rowChanged = Object.values(colsChanged).every(Boolean);
dark = rowChanged && rowIdx > 0 ? !dark : dark;
if (dark) {
tr.classList.add('dark');
}
});
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
th {
background: #a9a9a9;
}
td,
th {
border: 1px solid black;
text-align: center;
padding: 8px;
font-family: monospace;
font-size: 17px;
}
.dark {
background-color: #dddddd;
}
<body onload="myFunction()">
<table>
<thead>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germanyindgo</td>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Francisco Chang</td>
<td>Austria</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Helen Bennett</td>
<td>UK</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td>Canada</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti 1</td>
<td>Giovanni Rovelli 1</td>
<td>Italy</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti 2</td>
<td>Giovanni Rovelli 2</td>
<td>Italy</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti 3</td>
<td>Giovanni Rovelli 3</td>
<td>Italy</td>
</tr>
</tbody>
</table>
</body>
根据下面的评论,如果您希望只有在第一列中合并了相应的单元格时才将单元格合并到右侧,这里有一个修改。
leftMerged
变量用于跟踪当前行的第一个单元格是否合并到前一个单元格,如果是,这使我们能够将后面的单元格合并到右侧,如果必要的。该变量在每行的开头重置为 false。
function myFunction() {
const previousRow = {};
const colsChanged = {};
let leftMerged = false;
let dark = false;
Array.from(document.querySelectorAll('tbody tr')).forEach((tr, rowIdx) => {
Array.from(tr.children).forEach((td, colIdx) => {
if (rowIdx > 0 && (colIdx === 0 || leftMerged) && previousRow[colIdx].text === td.innerText) {
previousRow[colIdx].elem.setAttribute('rowspan', ++previousRow[colIdx].span);
colsChanged[colIdx] = false;
td.remove();
if (colIdx === 0) {
leftMerged = true;
}
} else {
previousRow[colIdx] = { span: 1, text: td.innerText, elem: td, dark };
colsChanged[colIdx] = true;
}
});
const rowChanged = Object.values(colsChanged).every(Boolean);
dark = rowChanged && rowIdx > 0 ? !dark : dark;
if (dark) {
tr.classList.add('dark');
}
leftMerged = false;
});
}
table {
font-family: arial, sans-serif;
border-collapse: collapse;
width: 100%;
}
th {
background: #a9a9a9;
}
td,
th {
border: 1px solid black;
text-align: center;
padding: 8px;
font-family: monospace;
font-size: 17px;
}
.dark {
background-color: #dddddd;
}
<body onload="myFunction()">
<table>
<thead>
<tr>
<th>Company</th>
<th>Contact</th>
<th>Country</th>
<th>Col4</th>
<th>Col5</th>
</tr>
</thead>
<tbody>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germanyindgo</td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Francisco Chang</td>
<td>Austria</td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>Ernst Handel</td>
<td>Helen Bennett</td>
<td>UK</td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>Laughing Bacchus Winecellars</td>
<td>Yoshi Tannamuri</td>
<td>Canada</td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti 1</td>
<td>Giovanni Rovelli 1</td>
<td>Italy</td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti 1</td>
<td>Giovanni Rovelli 2</td>
<td>Italy</td>
<td>1</td>
<td>2</td>
</tr>
<tr>
<td>Magazzini Alimentari Riuniti 3</td>
<td>Giovanni Rovelli 3</td>
<td>Italy</td>
<td>1</td>
<td>2</td>
</tr>
</tbody>
</table>
</body>
关于javascript - 使用 JavaScript 合并表行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54591184/