如何检测复选框选中状态,新增条件后重新执行计算函数
点餐菜单价格计算功能实现方案
核心实现逻辑
多复选框选中计数的实现非常简单,不需要给单个复选框绑定独立判断逻辑,按以下思路处理即可:
- 用
document.querySelectorAll('input[name="NDLS"]:checked')获取所有已选中的面类复选框,返回的是一个DOM集合,集合的length属性就是当前选中的面类数量,判断length >= 2即可触发多面类对应的业务逻辑 - 把所有计价、区域禁用/启用逻辑统一放到同一个计算函数中,面类复选框、主菜单选、配餐单选的点击事件都触发这个函数,避免多函数分散调用导致的计算不同步问题
- 修复现有HTML的语法问题:原代码中4个面类复选框重复使用了相同id
PNDLS、label的for属性指向不存在的元素,不符合HTML规范,会导致DOM选择异常,直接移除冗余的重复id和错误for属性即可 - 计价规则按你给出的示例校准:基础价为「主菜价格 * 配餐倍率」,每选中1种面类,总价在基础价上增加25%,选中2种面类时刚好加价50%,匹配你给出的「基础价120美元、选2种面最终180美元」的示例,如果需要调整加价幅度,直接修改代码中对应的倍率系数即可
修正后完整代码
JS逻辑部分
// 统一计价函数,所有选项变更都触发该函数 function calculateTotal() { // 统计选中的面类数量,控制主菜、配餐区域的禁用状态 const selectedNoodles = document.querySelectorAll('input[name="NDLS"]:checked'); const noodleCount = selectedNoodles.length; const mainDishArea = document.getElementById("MMD"); const addonArea = document.getElementById("ADDONS"); if (noodleCount > 0) { mainDishArea.disabled = false; addonArea.disabled = false; } else { mainDishArea.disabled = true; addonArea.disabled = true; // 未选面时清空已选内容和价格 document.querySelectorAll('input[name="MD"]:checked, input[name="ADDONS"]:checked').forEach(el => el.checked = false); document.getElementById("amount").value = ''; return; } // 校验主菜、配餐是否已选择,未选则不计算价格 const selectedMain = document.querySelector('input[name="MD"]:checked'); const selectedAddon = document.querySelector('input[name="ADDONS"]:checked'); if (!selectedMain || !selectedAddon) { document.getElementById("amount").value = ''; return; } // 价格计算 const mainPrice = Number(selectedMain.value); const addonRate = Number(selectedAddon.value); const basePrice = mainPrice * addonRate; // 面类加价系数,需要调整规则直接修改0.25这个值即可 const noodleRate = 1 + noodleCount * 0.25; const finalPrice = basePrice * noodleRate; document.getElementById("amount").value = finalPrice; }
HTML结构部分
<fieldset id="MNDLS"> <legend>Noodles</legend> <input type="checkbox" name="NDLS" value="0.5" onclick="calculateTotal()"> <label>Spaghetti</label><br> <input type="checkbox" name="NDLS" value="0.5" onclick="calculateTotal()"> <label>Carbonara</label><br> <input type="checkbox" name="NDLS" value="0.5" onclick="calculateTotal()"> <label>Lasagna</label><br> <input type="checkbox" name="NDLS" value="0.5" onclick="calculateTotal()"> <label>Plain</label> </fieldset> <fieldset id="MMD" disabled> <legend>Main Dish</legend> <input type="radio" name="MD" value="50" onclick="calculateTotal()"> <label>Chicken Wings ($50)</label><br> <input type="radio" name="MD" value="55" onclick="calculateTotal()"> <label>Chicken Breast ($55)</label><br> <input type="radio" name="MD" value="60" onclick="calculateTotal()"> <label>Pork Cutlets ($60)</label><br> <input type="radio" name="MD" value="65" onclick="calculateTotal()"> <label>Steak($65)</label> </fieldset> <fieldset id="ADDONS" disabled> <legend>Sides</legend> <input type="radio" name="ADDONS" value="1" onclick="calculateTotal()"> <label>Nothing (100%)</label><br> <input type="radio" name="ADDONS" value="1.5" onclick="calculateTotal()"> <label>Softdrinks (150%)</label><br> <input type="radio" name="ADDONS" value="2" onclick="calculateTotal()"> <label>Softdrinks and Fries (200%)</label> </fieldset> <br> <p><strong>Amount (US$)</strong>: <input type="text" name="amount" id="amount" value="" readonly /></p>
补充说明
- 如果需要单独添加选中2种及以上面类的特殊逻辑,直接在拿到
noodleCount变量后增加判断if (noodleCount >= 2) { // 写入对应业务逻辑 }即可 - 价格输入框添加了
readonly属性,避免用户手动修改价格 - 所有从DOM中获取的input值默认是字符串类型,计算前用
Number()转成数字类型,避免出现字符串拼接的异常计算结果
内容的提问来源于stack exchange,提问作者bushi
相关产品推荐
相关产品推荐

