Jquery购物车多行列修改数量出现NaN错误技术求助
解决购物车多行数据修改数量出现NaN的问题
我来帮你搞定这个NaN的bug!咱们先拆解下原来代码里的几个核心问题:
问题根源
- 重复的ID属性:所有数量输入框都用了
id="quantity",但ID在页面中必须是唯一的,jQuery用$('#quantity')只会选中第一个输入框,多行数据时完全无法正确获取当前修改的数量。 - 全局选择器导致文本拼接:
$('.price').text()会把所有行的价格文本拼在一起(比如变成₹360.00 ₹360.00),尝试把这个字符串转成数字时就会得到NaN。 - 小计更新范围错误:
$('.total').text(...)会把所有行的小计都改成同一个值,完全不符合每行独立计算的需求。 - 总计计算逻辑错误:原来的PHP代码在循环外计算总计,只会取最后一行商品的价格,导致总计显示错误。
修复后的完整代码
1. 修改PHP生成表格的代码
<table class="table"> <thead> <tr> <th class="pro-remove">Remove</th> <th class="pro-thumbnail">Image</th> <th class="pro-title">Product</th> <th class="pro-price">Price</th> <th class="pro-quantity">Quantity</th> <th class="pro-subtotal"> Total</th> </tr> </thead> <tbody> <?php $cartid = $_GET['proid']; $sqlpd = mysql_query("select * from orderdetail LEFT JOIN products ON orderdetail.product_id = products.product_id where sessionid='$session_id'")or die(mysql_error()); // 初始化总计变量,放在循环外 $tot_amt = 0; $gst_amt = 0; while($getpd = mysql_fetch_array($sqlpd)){ $product_id = $getpd['product_id']; $actual_price = $getpd['actual_price']; $commission_amount = $getpd['commission_amount']; // 循环内累加小计和GST $tot_amt += $actual_price; $gst_amt += $commission_amount; ?> <tr class="cart-item"> <td class="pro-remove"><a href="javascript:void(0);" name="cart_remove" class="cart_remove delete"><i class="fa fa-trash-o"></i></a></td> <td class="pro-thumbnail"> <img src="admin/<?php echo $getpd['medium_image'];?>" height="50" width="50"> </td> <td class="pro-title"><?php echo $getpd['product_id'];?></td> <td class="pro-price"> <!-- 用data-price存储纯数字价格,避免后续解析文本 --> <span class="price" data-price="<?php echo $actual_price; ?>"> <i class="fa fa-inr"></i><?php echo number_format($actual_price,2);?> </span> </td> <td class="pro-quantity"> <!-- 移除重复ID,用类标识输入框 --> <input type="number" class="cardqty-1 quantity-input" min="1" value="1" name="quantity" style="width:50px;"> <a href="javascript:void();" class="updatecart" data-id="1" data-prd_id="<?php echo $product_id;?>" data-rowid="c2b5d53083a7597dd75ac36d9fd93581"><i class="fa fa-refresh" aria-hidden="true"></i></a> </td> <td class="pro-subtotal"> <!-- 用item-total区分行小计和全局总计 --> <span class="item-total"> <i class="fa fa-inr"></i><?php echo number_format($actual_price,2);?> </span> </td> </tr> <?php }?> </tbody> <tfoot> <tr> <th></th> <th></th> <th></th> <th></th> <th>Sub Total</th> <th class="pro-subtotal text-center"> <span class="sub-total"> <i class="fa fa-inr"></i><?php echo number_format($tot_amt,2);?> </span> </th> </tr> <tr> <th></th> <th></th> <th></th> <th></th> <th>GST(12%)</th> <th class="pro-subtotal text-center"> <span class="gst-total"> <i class="fa fa-inr"></i><?php echo number_format($gst_amt,2);?> </span> </th> </tr> <tr> <th></th> <th></th> <th></th> <th></th> <th>Grand Total</th> <th class="pro-subtotal text-center"> <span class="grand-total"> <i class="fa fa-inr"></i><?php echo number_format($tot_amt + $gst_amt,2);?> </span> </th> </tr> </tfoot> </table>
2. 修改jQuery脚本
<script type="text/javascript"> $(document).ready(function() { // 监听所有数量输入框的变化事件 $('.quantity-input').on('change keyup click', function() { // 获取当前输入框所在的购物车行,确保只操作当前行的数据 var $currentRow = $(this).closest('.cart-item'); // 从data-price获取纯数字价格,避免解析带货币符号的文本 var productPrice = parseFloat($currentRow.find('.price').data('price')); // 获取当前数量,确保是有效数字,默认值为1 var currentQty = parseInt($(this).val()) || 1; // 计算当前行的小计并保留两位小数 var rowSubtotal = (productPrice * currentQty).toFixed(2); // 更新当前行的小计显示 $currentRow.find('.item-total').html('<i class="fa fa-inr"></i>' + rowSubtotal); // 每次修改数量后重新计算全局总计 updateGlobalTotals(); }); // 计算并更新全局总计的函数 function updateGlobalTotals() { var totalSub = 0; var totalGst = 0; // 遍历所有购物车行,累加每行的小计 $('.cart-item').each(function() { // 提取小计文本中的纯数字部分 var itemTotalStr = $(this).find('.item-total').text().replace(/[^0-9.]/g, ''); var itemTotal = parseFloat(itemTotalStr) || 0; totalSub += itemTotal; // 如果GST是固定比例(12%),直接计算;如果是数据库存储的值,可以从data属性获取 totalGst += itemTotal * 0.12; }); // 更新页面上的全局总计显示 $('.sub-total').html('<i class="fa fa-inr"></i>' + totalSub.toFixed(2)); $('.gst-total').html('<i class="fa fa-inr"></i>' + totalGst.toFixed(2)); $('.grand-total').html('<i class="fa fa-inr"></i>' + (totalSub + totalGst).toFixed(2)); } }); </script>
修复说明
- 行级数据隔离:通过
closest('.cart-item')锁定当前操作的购物车行,确保价格、数量、小计的操作都只针对当前行,不会影响其他行。 - 避免文本解析错误:用
data-price存储纯数字价格,直接读取数字进行计算,彻底解决了带货币符号的文本转数字导致的NaN问题。 - 唯一标识与类选择器:移除重复的ID,改用类选择器操作元素,符合HTML规范。
- 动态计算全局总计:每次修改数量后自动重新计算所有总计,确保数据实时同步。
内容的提问来源于stack exchange,提问作者sixthstar
相关产品推荐
相关产品推荐

