动态表格行内计算问题:Keyup事件失效与新增行功能冲突
解决表格行内动态数值计算问题
看起来你遇到了动态表格行的事件绑定和数值计算的棘手问题,我帮你整理了一套完整的解决方案,修复了之前的代码缺陷,同时实现了你需要的所有计算逻辑:
完整代码实现
HTML部分(修复原结构的语法问题)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <table class="table"> <thead> <tr> <th scope="col">Category</th> <th scope="col">Item</th> <th scope="col">Per Unit</th> <th scope="col">Quantity</th> <th scope="col">Initial</th> <th scope="col">Discount</th> <th scope="col">Area</th> <th scope="col">NETT</th> <th scope="col">FOC</th> <th scope="col">Total</th> <th scope="col">Remove</th> </tr> </thead> <tbody id="myTable"> </tbody> </table> <u onclick="myCreateFunction()" style="cursor:pointer;margin-left:5px">+Add Order</u>
JavaScript部分(修复逻辑+实现全流程计算)
function myCreateFunction() { var tbody = document.getElementById("myTable"); var row = tbody.insertRow(-1); // 修复了class重复的语法错误:合并为单个class属性 row.innerHTML = ` <td><input type='text' class='form-control Category' name='Category[]' placeholder='Category'></td> <td><input type='text' class='form-control Item' name='Item[]' placeholder='Item'></td> <td><input type='text' class='form-control PerUnit' name='PerUnit[]' placeholder='Per Unit' readonly></td> <td><input type='text' class='form-control Quantity' name='Quantity[]' placeholder='Quantity'></td> <td><input type='text' class='form-control Initial' name='Initial[]' placeholder='Initial' readonly></td> <td><input type='text' class='form-control Discount' name='Discount[]' placeholder='Discount'></td> <td><input type='text' class='form-control Area' name='Area[]' placeholder='Area'></td> <td><input type='text' class='form-control NETT' name='NETT[]' placeholder='NETT'></td> <td><input type='checkbox' class='form-control FOC' name='FOC[]'></td> <td><input type='text' class='form-control Total' name='Total[]' placeholder='Total' readonly></td> <td><button class='close' aria-label='Close'><span aria-hidden='true'>×</span></button></td> `; } // 移除行的事件委托(保留原有效逻辑) $('#myTable').on('click', '.close', function() { $(this).closest('tr').remove(); }); // 1. Item输入/选择后自动获取对应Per Unit单价 $('#myTable').on('change keyup', '.Item', function() { const currentRow = $(this).closest('tr'); const itemName = $(this).val().trim(); if (!itemName) return; // 替换为你的实际数据库请求逻辑(示例用模拟数据) // 比如用$.ajax调用后端接口获取单价 const mockUnitPrice = 15; // 这里替换成接口返回的真实单价 currentRow.find('.PerUnit').val(mockUnitPrice); // 单价获取后自动计算Initial calculateInitial(currentRow); }); // 2. 输入Quantity时自动计算Initial(PerUnit * Quantity) $('#myTable').on('keyup', '.Quantity', function() { const currentRow = $(this).closest('tr'); calculateInitial(currentRow); }); // 3. 折扣变化或FOC勾选时自动计算Total $('#myTable').on('keyup change', '.Discount, .Area, .FOC', function() { const currentRow = $(this).closest('tr'); calculateTotal(currentRow); }); // 计算Initial的通用函数 function calculateInitial(row) { const perUnit = parseFloat(row.find('.PerUnit').val()) || 0; const quantity = parseFloat(row.find('.Quantity').val()) || 0; const initial = perUnit * quantity; row.find('.Initial').val(initial.toFixed(2)); // Initial更新后同步计算Total calculateTotal(row); } // 计算Total的通用函数 function calculateTotal(row) { const initial = parseFloat(row.find('.Initial').val()) || 0; const discount = parseFloat(row.find('.Discount').val()) || 0; const areaDiscount = parseFloat(row.find('.Area').val()) || 0; const isFOC = row.find('.FOC').is(':checked'); // 折扣按百分比计算(输入10代表10%折扣),如果是固定金额可直接修改逻辑 const total = isFOC ? 0 : initial * (1 - (discount + areaDiscount)/100); row.find('.Total').val(total.toFixed(2)); }
关键修复与优化说明
- 修复class重复问题:原代码中每个input元素写了两次
class属性(比如class='form-control Category' class='Category'),这是无效的HTML语法,会导致样式和选择器失效,现在合并为单个class属性。 - 事件委托机制:所有动态生成元素的事件都通过父元素
#myTable委托绑定,彻底解决了新增行无法触发事件的问题。 - 精准行定位:通过
$(this).closest('tr')获取当前操作的行,再用find()定位该行内的其他输入框,确保计算只针对当前行,不会干扰其他行的数据。 - 模块化计算逻辑:把Initial和Total的计算拆分为独立函数,代码更清晰,后续修改计算规则也更方便。
自定义提示
- 记得把
Item事件中的模拟单价替换成实际的后端接口请求(比如用$.ajax)。 - 如果你的折扣是固定金额而非百分比,直接修改
calculateTotal里的计算逻辑即可。 - FOC复选框勾选时Total会设为0,若有其他需求可调整这部分逻辑。
内容的提问来源于stack exchange,提问作者Doing Life
相关产品推荐
相关产品推荐

