使用JavaScript addEventListener更新商品小计失效问题求助
问题分析与修复方案
问题现象
点击加减按钮时,无法正常根据商品单价(Rp 12.500)和数量计算更新小计:
- 将数量改为1后点击加号,数量会异常变为0
- 控制台能输出数据,但页面上的小计输入框无变化
错误原因
- 不规范的变量引用:代码中已通过
document.getElementById获取了quantity和subTotal元素变量,但后续所有逻辑都直接使用元素ID(如quantity1.value)作为全局变量访问,依赖浏览器自动映射ID到全局的特性,这一行为不稳定,容易导致元素引用失效,引发数值计算异常。 - 数值异常未处理:当数量输入框的值无法转换为有效数字时,未做默认值处理,会导致计算结果异常。
修复后的代码
<body> <section class="section dashboard"> <form action="http://127.0.0.1:4321/pembelian/add/create" method="POST"> <input type="hidden" name="_token" value="zwlU7e6su5TVTxRAWZiXnMMdMFDrVZtk5WATlXWT" autocomplete="off"> <div class="col text-end mb-4"> <button type="submit" class="btn btn-outline-primary" id="submitButton" fdprocessedid="fh7vd">Buat Pesanan</button> </div> <div class="row"> <div class="col-lg-4"> <div class="card"> <div class="image-container" style="width: 200px; height: 150px; background-color: white; display: flex; justify-content: center; align-items: center;"> <img src="http://127.0.0.1:4321/assets/images/storage/../eskrim.jpg" class="card-img-top" alt="storage/../eskrim.jpg" style="max-width: 100%; max-height: 100%; object-fit: contain;"> </div> <div class="card-body text-center"> <h5 class="card-title">Es Krim</h5> <p class="card-text">Rp 12.500</p> <p class="card-text">13</p> <div class="flex flex-col gap-0 items-center"> <input type="hidden" name="produkId[1]" value="1" id="produkId1"> <div class="flex flex-row gap-0 items-center justify-center w-full"> <button type="button" id="button-min1" class="border-0 focus:outline-none" fdprocessedid="g7pore">-</button> <input class="input-quantity border-0 bg-transparent focus:outline-none focus:ring-0" type="number" name="total_produk[1]" value="0" min="0" max="100" id="quantity1" fdprocessedid="wlgdxd"> <button type="button" id="button-plus1" class="border-0 font-semibold focus:outline-none" fdprocessedid="rkul0jd">+</button> </div> <div class="flex flex-row w-full"> <span class="border-0">Subtotal : Rp</span> <input id="subTotal1" value="0" type="text" class="border-0 text-sm text-start bg-transparent" disabled="" fdprocessedid="b4zjhr"> </div> </div> </div> </div> </div> <script> var minOp = document.getElementById('button-min1'); var plusOp = document.getElementById('button-plus1'); var quantity = document.getElementById('quantity1'); var subTotal = document.getElementById('subTotal1'); var submitButton = document.getElementById('submitButton'); minOp.addEventListener('click', function() { var value = parseInt(quantity.value); if (!isNaN(value) && value > 0) { quantity.value = value - 1; } calcSubtotal1() }) plusOp.addEventListener('click', function() { var value = parseInt(quantity.value); if (!isNaN(value)) { quantity.value = value + 1; } calcSubtotal1() console.log('更新后数量:', quantity.value); }) function calcSubtotal1() { var price = 12500.00; var qty = parseInt(quantity.value) || 0; // 处理无效数值,默认设为0 var subTotals = price * qty; subTotal.value = number_format(subTotals, 0, ',', '.'); console.log('更新后小计:', subTotal.value); }; function number_format (number, decimals, dec_point, thousands_sep) { number = (number + '').replace(/[^0-9+-Ee.]/g, ''); var n = !isFinite(+number) ? 0 : +number, prec = !isFinite(+decimals) ? 0 : Math.abs(decimals), sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep, dec = (typeof dec_point === 'undefined') ? '.' : dec_point, s = '', toFixedFix = function (n, prec) { var k = Math.pow(10, prec); return '' + Math.round(n * k) / k; }; s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.'); if (s[0].length > 3) { s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep); } if ((s[1] || '').length < prec) { s[1] = s[1] || ''; s[1] += new Array(prec - s[1].length + 1).join('0'); } return s.join(dec); } </script> </body>
修复说明
- 统一使用预先获取的
quantity和subTotal变量访问元素,避免依赖浏览器的ID全局映射特性,确保元素引用稳定可靠。 - 在计算小计的函数中,增加
|| 0处理数量转换为NaN的情况,避免出现非数值计算结果。 - 调整控制台日志,打印更新后的数量和小计值,方便调试。
内容的提问来源于stack exchange,提问作者ndreander
相关产品推荐
相关产品推荐

