使用jQuery计算循环生成的文本框值失败,寻求修复方案
搞定循环生成元素的NaN计算问题
我帮你排查了循环代码里的几个关键问题,正是这些问题导致了总和计算出现NaN错误,下面是详细分析和修复方案:
先说说核心错误点
- jQuery选择器写错了! 你写的
$("turadetler_@id")少了类选择器的.,jQuery根本找不到对应的元素,遍历的时候自然拿不到有效值,计算就成NaN了。 - 小数格式不兼容:看你循环生成的示例里,单价是
"0,2"(用逗号当小数分隔符),但parseFloat只认点号,直接转的话就会得到NaN。 - 单价变量没及时更新:你把
birim_@id放在$(document).ready里初始化,要是用户修改了单价输入框的值,这个变量不会同步更新,而且它还是字符串类型,直接参与乘法也容易出问题。 - 重复绑定事件:循环里每个div都塞了一个
$(document).ready,会导致同一个元素被多次绑定事件,既浪费性能又可能出逻辑问题。
修复后的完整代码
我把这些问题都修正了,还优化了事件绑定逻辑,代码如下:
<div class="row verigirisler_@id" id="turdiv_@id" style="display:none"> @{ foreach (var tbirimfiyat in ViewBag.TurlerBirimFiyat) { if (item.Musteri_ID == tbirimfiyat.Musteri_ID && tur.Tur_ID == tbirimfiyat.Tur_ID) { <input type="text" class="turbirimfiyat" id="turbirfiyat_@id" name="Musteri_ID" value="@tbirimfiyat.tBirim_Fiyat" /> } } } <div class="col mb-1"> <div class="input-group"> <div class="input-group-append"> <span class="input-group-text bg-success">Verilen @tur.Tur_Ad</span> <!-- 新增data-id属性,方便后续获取ID后缀 --> <input type="number" value="0" id="verilen_@id" class="form-control turadetler turadetler_@id" name="verilen" data-id="@id"> </div> </div> </div> <div class="col mb-1"> <div class="input-group"> <div class="input-group-append"> <span class="input-group-text ml-3 bg-success">Alınan @tur.Tur_Ad</span> <input type="number" class="form-control turadetler turadetler_@id" id="alinan_@id" name="alinan" value="0" data-id="@id"> </div> </div> </div> <div class="col mb-1"> <div class="input-group"> <div class="input-group-append"> <span class="input-group-text ml-3 bg-success">Alınan Para</span> <input type="number" class="form-control" id="para_@id" name="para" value="0"> </div> </div> </div> </div> <!-- 把脚本移到循环外面,统一处理所有组的计算 --> <script type="text/javascript"> $(document).ready(function() { // 给所有数量输入框绑定事件 $(".turadetler").on("keydown keyup", function() { // 通过data-id获取当前组的ID后缀,比解析class更可靠 var idSuffix = $(this).data('id'); // 处理单价:把逗号转成点,转成数字,无效的话默认0 var birim = parseFloat($('#turbirfiyat_' + idSuffix).val().replace(',', '.')) || 0; var sum = 0; // 遍历当前组的所有数量输入框 $(".turadetler_" + idSuffix).each(function() { var val = parseFloat($(this).val().replace(',', '.')); // 检查值是否有效 if (!isNaN(val)) { if (val !== 0) { sum += val * birim; $(this).css("background-color", "#FEFFB0"); } } else if ($(this).val().length > 0) { // 输入无效内容时标红 $(this).css("background-color", "red"); } }); // 设置总和,保留两位小数,确保是合法数字 $("#para_" + idSuffix).val(sum.toFixed(2)); }); // 额外:给单价输入框也绑定事件,修改单价时自动重新计算 $(".turbirimfiyat").on("keydown keyup", function() { var idSuffix = $(this).attr('id').replace('turbirfiyat_', ''); // 触发当前组的数量输入框事件,重新计算 $(".turadetler_" + idSuffix).first().trigger('keyup'); }); }); </script>
重点修复说明
- 修正选择器:所有class选择器都加上了
.,比如$(".turadetler_@id"),jQuery现在能正确找到元素了。 - 处理小数分隔符:用
replace(',', '.')把逗号转成点,解决了欧洲格式小数无法被parseFloat识别的问题。 - 动态获取单价:每次计算时都重新获取并转换单价,确保修改单价后总和能同步更新,还用
|| 0处理了无效值的情况。 - 统一事件绑定:把脚本移到循环外,通过公共class
turadetler绑定事件,避免了重复绑定的问题,还新增了单价修改时自动计算的逻辑。 - 更可靠的ID获取:用
data-id属性存储组ID,比解析class更不容易出错。
额外小提示
如果你的项目里小数分隔符是动态的(比如根据用户地区),可以考虑用Intl.NumberFormat来处理,不过当前用replace(',', '.')已经能解决你的问题啦。
内容的提问来源于stack exchange,提问作者Jr. Developer
相关产品推荐
相关产品推荐

