如何解决同属性div表单name重复导致的商品价格计算异常问题
解决方案
核心思路是限定DOM查询范围为当前操作的商品容器,避免全局查询拉取到其他商品的同名元素,具体修改如下:
1. 先修复已知HTML问题
先修正两个明显的HTML错误,避免后续逻辑异常:
- 所有元素id必须全局唯一,你现在两个商品块里的
houseEspresso、guestEspresso、none等id重复,会导致label点击关联失效,可以给每个id加上商品前缀,比如意式浓缩的id改成espresso-houseEspresso,卡布奇诺的改成cappuccino-houseEspresso - 卡布奇诺的size单选框同时给
medium和large加了checked属性,会导致默认选中逻辑异常,删掉其中一个的checked属性即可
2. 修改价格计算逻辑
你已经在onclick里传入了this(当前触发点击的输入框元素),直接基于这个元素向上找到所属的商品容器(class为option的div),所有后续查询都在这个容器内执行:
function addProduct(activeEl) { // 向上查找当前输入框所属的商品根容器 let productContainer = activeEl.closest('.option'); // 仅在当前商品容器内查询size、extra元素 let size = productContainer.querySelectorAll('input[name="size"]'); let extra = productContainer.querySelectorAll('input[name="extra"]'); // 仅查询当前商品对应的价格显示元素 let priceEl = productContainer.querySelector('.product-price'); let priceOfSize = 0; let priceOfExtra = 0; for (let i = 0; i < size.length; i++) { if (size[i].checked) { priceOfSize = parseFloat(size[i].value); break; // 单选框找到选中项直接跳出循环 } } for (let i = 0; i < extra.length; i++) { if (extra[i].checked) { priceOfExtra += parseFloat(extra[i].value); } } let priceOfProduct = priceOfSize + priceOfExtra; priceEl.innerText = priceOfProduct.toFixed(2); }
3. 加入购物车逻辑补充
如果需要把当前商品加入购物车,同样在当前容器内获取商品信息即可:
// 给所有加入购物车按钮绑定点击事件 document.querySelectorAll('.btn-cart').forEach(btn => { btn.addEventListener('click', function() { let productContainer = this.closest('.option'); // 获取商品类型:从容器id中提取 let productType = productContainer.id.replace('-option', ''); // 获取当前商品价格 let productPrice = parseFloat(productContainer.querySelector('.product-price').innerText); // 获取选中的类型、尺寸、附加项 let selectedType = productContainer.querySelector('input[name="type"]:checked + label').innerText; let selectedSize = productContainer.querySelector('input[name="size"]:checked + label').innerText; let selectedExtras = Array.from(productContainer.querySelectorAll('input[name="extra"]:checked + label')).map(el => el.innerText); // 这里写你自己的加入购物车逻辑,比如把上面的信息push到购物车数组 console.log('加入购物车:', { type: productType, spec: selectedType, size: selectedSize, extras: selectedExtras, price: productPrice }); }); });
修改后每个商品的操作只会在自身容器内查询元素,完全不会互相干扰,不需要引入任何第三方框架,纯原生JS即可实现。
内容的提问来源于stack exchange,提问作者Chris Ho
相关产品推荐
相关产品推荐

