如何让getPaymentAmount函数在多次调用间保存变量实现总价累加?
问题描述
我给多个HTML select元素绑定了getPaymentAmount(this)的触发逻辑,现在想实现:选第一个select时保存当前价格,后续选其他select时,把所有选中的价格累加计算总价。
我的HTML代码:
<div id="trim_list"> <div class="w3-row w3-padding"> <div class="w3-col m6"> <label for="type_trim_1">Type of Trim for horse 1:</label> </div> <div class="w3-col m6"> <select id="type_trim_1" class="w3-input w3-border w3-border-black addCost" name="type_trim[]" onChange="getPaymentAmount(this);" required=""> <option value="">Select Type of Trim</option> <option value="40:trim">Regular Trim</option> <option value="130:front">Front Shoes</option> <option value="190:all">All Four Shoes</option> </select> </div> </div> <div class="w3-row w3-padding"> <div class="w3-col m6"> <label for="type_trim_2">Type of Trim for horse 2:</label> </div> <div class="w3-col m6"> <select id="type_trim_2" class="w3-input w3-border w3-border-black addCost" name="type_trim[]" onChange="getPaymentAmount(this);" required=""> <option value="">Select Type of Trim</option> <option value="40:trim">Regular Trim</option> <option value="130:front">Front Shoes</option> <option value="190:all">All Four Shoes</option> </select> </div> </div> <div class="w3-row w3-padding"> <div class="w3-col m6"> <label for="type_trim_3">Type of Trim for horse 3:</label> </div> <div class="w3-col m6"> <select id="type_trim_3" class="w3-input w3-border w3-border-black addCost" name="type_trim[]" onChange="getPaymentAmount(this);" required=""> <option value="">Select Type of Trim</option> <option value="40:trim">Regular Trim</option> <option value="130:front">Front Shoes</option> <option value="190:all">All Four Shoes</option> </select> </div> </div> </div> <!-- 显示总价的输入框 --> <input type="number" id="paid" readonly>
对应的JavaScript函数:
function getPaymentAmount(e){ let total = 0; // 存储总价 let val = e.value; // select的值,格式为40:trim/130:front/190:all let eleVal = val.split(':'); // 拆分价格和类型 let price = parseInt(eleVal[0]); // 转成数字 // 调试用弹窗 alert(price); // 选第一个选项时弹窗40 alert(typeof(price)); // 弹窗number // 疑问:怎么保存当前价格,让后续选其他select时能累加所有价格? $('paid').value = total; // 更新总价输入框 }
我试过递归保存第一个值但没成功;也试过统计select数量,但因为需要传递"价格:类型"的格式,循环处理时会出现NaN错误,而且元素是动态生成的,之前的方法不适用。
解决方案
核心思路:每次触发事件时,遍历所有select重新计算总价
这种方式不用维护外部状态变量,不管是静态还是动态生成的select,都能正确累加,还能避免空值导致的NaN问题。
修改后的JavaScript代码
function getPaymentAmount() { let total = 0; // 遍历所有带addCost类的select元素 document.querySelectorAll('.addCost').forEach(select => { const val = select.value; if (val) { // 跳过未选择的选项 const [priceStr] = val.split(':'); const price = parseInt(priceStr, 10); // 确保解析出来的是有效数字,再累加 if (!isNaN(price)) { total += price; } } }); // 更新总价输入框 document.getElementById('paid').value = total; }
调整HTML的触发逻辑
因为现在函数不需要接收单个元素参数,直接触发即可,把所有select的onChange改成:
onChange="getPaymentAmount();"
方案优势
- 每次计算都从头遍历所有select,不需要保存单个价格,避免状态不一致问题
- 增加两层判断:先判断select是否有选中值,再判断解析后的价格是否为有效数字,彻底避免NaN错误
- 依赖
addCost类定位元素,动态生成的select只要加上这个类,就能自动被纳入计算范围
内容的提问来源于stack exchange,提问作者Cavalier
相关产品推荐
相关产品推荐

