如何实现仅统计日期筛选后表格可见行的价格总和?
问题
现有一段代码可统计表格中所有价格单元格的总和,但需求是仅统计日期筛选后可见行的价格总和。目前切换日期范围后,表格仅显示对应日期的行,但价格总和仍计算所有行的数据,需要修改代码实现仅统计可见行的价格并更新<span id="val">中的数值。
现有代码如下:
JavaScript 代码
function filterRows() { var from = jQuery("#datefilterfrom").val(); var to = jQuery("#datefilterto").val(); if (!from && !to) { // no value for from and to return; } from = from || "1970-01-01"; // default from to a old date if it is not set to = to || "2999-12-31"; var dateFrom = moment(from); var dateTo = moment(to); jQuery("#table tr").each(function(i, tr) { var val = jQuery(tr).find("td:nth-child(2)").text(); var dateVal = moment(val, "DD.MM.YYYY"); var visible = (dateVal.isBetween(dateFrom, dateTo, null, [])) ? "" : "none"; // [] for inclusive jQuery(tr).css("display", visible); //summary start var table = document.getElementById("table"), sumVal = 0; for (var i = 1; i < table.rows.length; i++) { sumVal = sumVal + parseInt(table.rows[i].cells[2].innerHTML); } document.getElementById("val").innerHTML = "Sum Value = " + sumVal; console.log(sumVal); }); //summary end } jQuery("#datefilterfrom").on("change", filterRows); jQuery("#datefilterto").on("change", filterRows);
HTML 代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.4/moment.min.js"></script> <div class="row"> <div class="col-md-3"> <h4>Date from</h4> <input type="date" class="form-control" id="datefilterfrom" data-date-split-input="true"> <h4>Date to</h4> <input type="date" class="form-control" id="datefilterto" data-date-split-input="true"> </div> </div> <span id="val"></span> <table id="table" class="sortable"> <tr> <th>Name</th> <th>Date</th> <th>Price</th> </tr> <tr> <td>Name</td> <td>20.10.2020</td> <td>20</td> </tr> <tr> <td>Name</td> <td>21.10.2020</td> <td>25</td> </tr> <tr> <td>Name</td> <td>22.10.2020</td> <td>30</td> </tr> </table>
解决方案
核心修改点
- 移出循环内的求和逻辑:原代码把求和放在行遍历循环内部,会重复计算多次且统计所有行,属于冗余错误逻辑,需将求和逻辑移到行筛选完成后执行。
- 添加可见行判断:求和时仅计算
display属性不为none的行(即筛选后可见的行)。
修改后的完整JavaScript代码
function filterRows() { var from = jQuery("#datefilterfrom").val(); var to = jQuery("#datefilterto").val(); if (!from && !to) { // no value for from and to return; } from = from || "1970-01-01"; // default from to a old date if it is not set to = to || "2999-12-31"; var dateFrom = moment(from); var dateTo = moment(to); // 先完成所有数据行的筛选显示/隐藏 jQuery("#table tr").each(function(i, tr) { // 跳过表头行,保持始终可见 if (i === 0) return; var val = jQuery(tr).find("td:nth-child(2)").text(); var dateVal = moment(val, "DD.MM.YYYY"); var visible = (dateVal.isBetween(dateFrom, dateTo, null, [])) ? "" : "none"; // [] for inclusive jQuery(tr).css("display", visible); }); // 筛选完成后,统计可见行的价格总和 var table = document.getElementById("table"), sumVal = 0; for (var i = 1; i < table.rows.length; i++) { var row = table.rows[i]; // 判断当前行是否可见 if (window.getComputedStyle(row).display !== "none") { // 处理非数字价格,避免求和结果变为NaN var price = parseInt(row.cells[2].innerHTML); sumVal += isNaN(price) ? 0 : price; } } document.getElementById("val").innerHTML = "Sum Value = " + sumVal; console.log(sumVal); } jQuery("#datefilterfrom").on("change", filterRows); jQuery("#datefilterto").on("change", filterRows);
额外优化说明
- 跳过表头行:在筛选循环中添加判断,避免对表头行执行显示/隐藏操作,保证表头始终可见。
- 处理非数字价格:增加
isNaN判断,防止表格中出现非数字价格时导致求和结果异常。
内容的提问来源于stack exchange,提问作者Lubo Masura
相关产品推荐
相关产品推荐

