Checkbox全选/Shift批量选中时价格求和功能失效求助
问题描述
当前代码仅能在单个复选框选中/取消时正常计算价格总和,但以下场景下功能失效:
- 点击「Select All」全选后,取消任意复选框;
- 使用Shift键批量选中后,取消任意复选框。
需求:实时检测所有复选框的选中状态,将计算出的总价同步到「Sum」输入框中。
原代码
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="flex"> <table border="1"> <tr> <td> <input type="checkbox" id="selectAll" class="selectAll"> <label for="selectAll">Select All</label> </td> <td class="price"> Prices </td> </tr> <tr> <td> <input type="checkbox" class="checkbox" data-price="100000"> </td> <td class="price"> 100,000 </td> </tr> <tr> <td> <input type="checkbox" class="checkbox" data-price="200000"> </td> <td class="price"> 200,000 </td> </tr> <tr> <td> <input type="checkbox" class="checkbox" data-price="300000"> </td> <td class="price"> 300,000 </td> </tr> <tr> <td> <input type="checkbox" class="checkbox" data-price="400000"> </td> <td class="price"> 400,000 </td> </tr> </table> <div> <label for="sumPrice">Sum:</label> <input type="text" id="sumPrice" class="sumPrice" value="0"> </div> </div>
CSS
.flex{ display: flex; gap:10px; } table { margin-bottom:10px } table td { padding:5px; text-align:center; }
JavaScript
$(document).ready(function() { //SHIFT-SELECTED: var $chkboxes = $('.checkbox'); var lastChecked = null; $chkboxes.click(function(e) { if (!lastChecked) { lastChecked = this; return; } if (e.shiftKey) { var start = $chkboxes.index(this); var end = $chkboxes.index(lastChecked); $chkboxes.slice(Math.min(start,end), Math.max(start,end)+ 1).prop('checked', lastChecked.checked); } lastChecked = this; }); //SELECT-ALL: $('.selectAll').click(function() { if(this.checked) { $('.checkbox:checkbox').each(function() { this.checked = true; }); } else { $('.checkbox:checkbox').each(function() { this.checked = false; }); } }); $('input[type="checkbox"]').not('.selectAll').change(function(e) { if(this.checked) { var sumPrice = $(this).attr('data-price'); var sumPriceFloat = parseFloat(sumPrice); var sum = sumPriceFloat; $('.sumPrice').each(function() { var x = $(this).val(); sum += parseFloat(x || 0); }); $('.sumPrice').val(sum); } else { var sumPrice = $(this).attr('data-price'); var sumPriceFloat = parseFloat(sumPrice); var sum = sumPriceFloat; $('.sumPrice').each(function() { var x = $(this).val(); sum -= parseFloat(x || 0); }); $('.sumPrice').val(Math.abs(sum)); } }); });
解决方案
核心问题:批量操作(全选/Shift批量选)时未触发总价计算逻辑,且原加减逻辑易出现误差。修改思路:抽离统一的总价计算函数,所有复选框状态变化后都调用该函数重新统计总价。
修改后的JavaScript代码
$(document).ready(function() { var $chkboxes = $('.checkbox'); var lastChecked = null; var $sumInput = $('.sumPrice'); // 统一计算总价的函数 function calculateTotalPrice() { let total = 0; // 遍历所有选中的复选框,累加价格 $chkboxes.filter(':checked').each(function() { total += parseFloat($(this).data('price')); }); $sumInput.val(total); // 同步全选按钮状态:当所有复选框都选中时,自动勾选全选 $('.selectAll').prop('checked', $chkboxes.length === $chkboxes.filter(':checked').length); } // Shift批量选中逻辑 $chkboxes.click(function(e) { if (!lastChecked) { lastChecked = this; calculateTotalPrice(); // 单个点击时计算总价 return; } if (e.shiftKey) { var start = $chkboxes.index(this); var end = $chkboxes.index(lastChecked); $chkboxes.slice(Math.min(start, end), Math.max(start, end) + 1).prop('checked', lastChecked.checked); calculateTotalPrice(); // 批量操作后计算总价 } lastChecked = this; }); // 全选逻辑 $('.selectAll').click(function() { $chkboxes.prop('checked', this.checked); calculateTotalPrice(); // 全选操作后计算总价 }); // 单个复选框变化时计算总价 $chkboxes.change(calculateTotalPrice); // 页面初始化时计算一次总价 calculateTotalPrice(); });
关键修改说明
- 抽离
calculateTotalPrice函数:每次重新遍历所有选中的复选框,累加data-price值,彻底避免原加减逻辑的误差; - 全选/Shift批量操作后调用计算函数:确保批量操作后总价实时更新;
- 同步全选按钮状态:当手动选中所有复选框时,全选按钮自动勾选,提升交互体验;
- 单个复选框
change事件直接绑定计算函数:简化原逻辑,保证单个操作也能正确计算。
内容的提问来源于stack exchange,提问作者ramin
相关产品推荐
相关产品推荐

