yuanfan 问题简单,逻辑也简单,但代码写起来简直是白了少年头,因为太琐碎了。要是放在平时,打死我也不愿写这种代码,费时间还攒不了什么经验值。正好赶上这周休病假差不多已经复活、加上这两天难得有一丝丝活雷锋精神、以及过两天就是学习雷锋纪念日,我就当积德行善、拼尽耐心写一段笨拙的 JS 代码吧:
function mergeRows(table) {
const tbody = table.querySelector('tbody');
if (!tbody) return;
// 先验证每一行的单元格数量是否相同;若不同,就不尝试合并了(可能已经合并过)
const rows = tbody.querySelectorAll('tr'), nrow = rows.length;
if (nrow < 2) return;
let ncol = rows[0].querySelectorAll(':scope > td').length;
for (let i = 1; i < nrow; i++) {
if (rows[i].querySelectorAll(':scope > td').length !== ncol) return;
}
let delCells = []; // 待移除的重复单元格
// 寻找每一列上下相同的相邻单元格,并用 rowspan 属性合并之
for (let j = 0; j < ncol; j++) {
// 第 j 列里的所有单元格
let cells = tbody.querySelectorAll('tr > td:nth-child(' + (j + 1) + ')');
let k = 0; // 计数,看有几个相邻单元格相同
for (let i = 1; i < nrow; i++) {
// 向顶层单元格添加 rowspan 属性
function addRowSpan(i) {
if (k === 0) return;
rows[i].querySelector(':scope > td:nth-child(' + (j + 1) + ')')
.setAttribute('rowspan', k + 1);
}
if (cells[i].innerHTML === cells[i - 1].innerHTML) {
k++; // 两行相同的话,计数器 k 加一
delCells.push(cells[i]); // 事后删除当前单元格
// 若到达最后一行,至此合并
if (i == rows.length - 1) addRowSpan(i - k);
} else {
// 若相邻两行不同,那么着手合并之前找到的相同单元格
addRowSpan(i - 1 - k);
k = 0; // 重置计数器
}
}
}
delCells.forEach(cell => cell.remove());
}
找到页面上所有表格,合并相同单元格:
document.querySelectorAll('table').forEach(table => mergeRows(table));
好累,我得喘会儿。
不知道 ChatGPT 会不会几秒钟就写出来了。我还没玩过这东西。