JavaScript合并同年份表格行问题:代码无报错但未生效
解决表格相同年份行合并及金额累加问题
嘿,作为JS新手碰到这种表格行合并+数据累加的需求确实容易踩坑,我来帮你捋清楚问题出在哪,再给你一套可行的实现方案~
首先,先揪出你代码里的一个致命问题:你的ERB模板里,每个表格行的年份单元格都用了id="pin",如果金额列也是id="price"的话,这完全违反了HTML的规则——同一个页面里id必须唯一!浏览器的querySelector只会返回第一个匹配该id的元素,后面的行根本拿不到年份和金额数据,这大概率就是你的代码没生效的核心原因!
先把ERB代码改了,把重复的id换成class:
<tr class="<%= payment_paid(f.paid)%> paidrow"> <td> <% if !f.paid %> <%= check_box_tag "pin_number[]", f.id, checked= !f.paid? %> <%end%> </td> <td class="pin"><%= f.year %></td> <!-- 假设你的金额列是下面这样,同样把id改成class --> <td class="price"><%= f.price %></td> <!-- 其他列... --> </tr>
(顺便说一句:原来的tr用了id="paidrow",循环生成多行的话这个id也重复了,也得改成class哦)
接下来,我们写前端JS逻辑,核心思路是:先按年份把行分组,累加每组的金额,然后只保留每组的第一行,设置单元格的rowspan来实现合并,同时隐藏其他重复行。
把这段代码放在页面底部,或者用DOMContentLoaded确保DOM加载完成后再执行:
document.addEventListener('DOMContentLoaded', function() { // 获取所有目标表格行 const rows = document.querySelectorAll('tr.paidrow'); if (rows.length === 0) return; // 用对象分组,key是年份,value存总金额和对应的行集合 const yearGroups = {}; // 第一步:遍历所有行,分组并累加金额 rows.forEach(row => { // 提取年份,注意去掉前后空格 const year = row.querySelector('.pin').textContent.trim(); // 提取金额,处理掉非数字字符后转成数字 const priceStr = row.querySelector('.price').textContent.trim().replace(/[^0-9.]/g, ''); const price = parseFloat(priceStr) || 0; // 初始化分组 if (!yearGroups[year]) { yearGroups[year] = { total: 0, rows: [] }; } yearGroups[year].total += price; yearGroups[year].rows.push(row); }); // 第二步:处理每组的行合并 Object.values(yearGroups).forEach(group => { // 取出第一行和其他行 const [firstRow, ...otherRows] = group.rows; // 设置年份单元格的rowspan为组内行数,实现合并 const pinCell = firstRow.querySelector('.pin'); pinCell.setAttribute('rowspan', group.rows.length); // 更新第一行的金额为累加后的总数,保留两位小数(格式可按需调整) const priceCell = firstRow.querySelector('.price'); priceCell.textContent = `${group.total.toFixed(2)}`; // 隐藏其他重复的行 otherRows.forEach(row => { row.style.display = 'none'; }); }); });
再补充几个注意点:
- 如果你的表格是AJAX动态加载的(比如分页、筛选后重新渲染),那
DOMContentLoaded事件已经触发过了,这时候要把这段JS代码放在表格渲染完成的回调里执行,或者用MutationObserver监听表格的变化。 - 如果金额带千分位(比如
1,200.00),可以在转数字前先去掉逗号:priceStr.replace(/,/g, '')。 - 要是你需要合并其他列(比如和年份同组的其他单元格),可以参照年份单元格的方式设置
rowspan。
这样改完之后,应该就能实现你想要的相同年份行合并、金额累加的效果啦~
内容的提问来源于stack exchange,提问作者thepersonwho
相关产品推荐
相关产品推荐

