购物网站数量选择器代码重复问题:如何复用代码减少冗余?
问题:购物网站数量选择器代码重复,如何复用?
我开发了一个购物网站,但每个Quantity selector(数量选择器)都需要单独编写代码,导致大量重复代码。请问如何为每个数量选择器复用相同的代码?

以下是补充代码(因Stack Overflow不允许仅以代码为主提问,即便我的问题是如何减少代码量):
<tr> <td> <span id="price_log">2.23</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> <td> <span id="price_leaf">0.28</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> <td> <span id="price_stone">0.14</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> <td> <span id="price_melon">2.80</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> </tr> <tr> <td> <input type="button" value="-" onclick="updateQuantity('log', -1)"> <input type="number" id="log" value="0" min="0" onchange="updateQuantity('log', 0)"> <input type="button" value="+" onclick="updateQuantity('log', 1)"> <br> Total: <span id="total_log">0.00</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> <td> <input type="button" value="-" onclick="updateQuantity('leaf', -1)"> <input type="number" id="leaf" value="0" min="0" onchange="updateQuantity('leaf', 0)"> <input type="button" value="+" onclick="updateQuantity('leaf', 1)"> <br> Total: <span id="total_leaf">0.00</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> <td> <input type="button" value="-" onclick="updateQuantity('stone', -1)"> <input type="number" id="stone" value="0" min="0" onchange="updateQuantity('stone', 0)"> <input type="button" value="+" onclick="updateQuantity('stone', 1)"> <br> Total: <span id="total_stone">0.00</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> <td> <input type="button" value="-" onclick="updateQuantity('melon', -1)"> <input type="number" id="melon" value="0" min="0" onchange="updateQuantity('melon', 0)"> <input type="button" value="+" onclick="updateQuantity('melon', 1)"> <br> Total: <span id="total_melon">0.00</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> </tr>
解决方案
1. 用数据属性+事件委托减少重复代码
先修改HTML结构,用**数据属性(data-*)**关联商品信息,去掉硬编码的onclick/onchange,改用事件委托监听父容器的事件,实现通用逻辑:
修改后的HTML:
<tr> <td data-product="log"> <span class="price">2.23</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> <td data-product="leaf"> <span class="price">0.28</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> <td data-product="stone"> <span class="price">0.14</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> <td data-product="melon"> <span class="price">2.80</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> </tr> <tr id="quantity-container"> <td data-product="log"> <input type="button" value="-" class="quantity-btn" data-action="decrease"> <input type="number" class="quantity-input" value="0" min="0"> <input type="button" value="+" class="quantity-btn" data-action="increase"> <br> Total: <span class="total">0.00</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> <td data-product="leaf"> <input type="button" value="-" class="quantity-btn" data-action="decrease"> <input type="number" class="quantity-input" value="0" min="0"> <input type="button" value="+" class="quantity-btn" data-action="increase"> <br> Total: <span class="total">0.00</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> <td data-product="stone"> <input type="button" value="-" class="quantity-btn" data-action="decrease"> <input type="number" class="quantity-input" value="0" min="0"> <input type="button" value="+" class="quantity-btn" data-action="increase"> <br> Total: <span class="total">0.00</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> <td data-product="melon"> <input type="button" value="-" class="quantity-btn" data-action="decrease"> <input type="number" class="quantity-input" value="0" min="0"> <input type="button" value="+" class="quantity-btn" data-action="increase"> <br> Total: <span class="total">0.00</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> </td> </tr>
对应的通用JavaScript:
// 监听增减按钮点击 document.getElementById('quantity-container').addEventListener('click', function(e) { const target = e.target; if (!target.classList.contains('quantity-btn')) return; const productTd = target.closest('[data-product]'); const productName = productTd.dataset.product; const input = productTd.querySelector('.quantity-input'); const price = parseFloat(document.querySelector(`[data-product="${productName}"] .price`).textContent); const totalSpan = productTd.querySelector('.total'); let quantity = parseInt(input.value); quantity = target.dataset.action === 'increase' ? quantity + 1 : Math.max(0, quantity - 1); input.value = quantity; totalSpan.textContent = (quantity * price).toFixed(2); }); // 监听输入框直接修改 document.getElementById('quantity-container').addEventListener('change', function(e) { const target = e.target; if (!target.classList.contains('quantity-input')) return; const productTd = target.closest('[data-product]'); const productName = productTd.dataset.product; const price = parseFloat(document.querySelector(`[data-product="${productName}"] .price`).textContent); const totalSpan = productTd.querySelector('.total'); let quantity = parseInt(target.value); quantity = isNaN(quantity) ? 0 : Math.max(0, quantity); target.value = quantity; totalSpan.textContent = (quantity * price).toFixed(2); });
2. 封装模板动态生成(适合新增商品场景)
如果后续要加更多商品,可以把数量选择器封装成模板,通过JavaScript循环生成,彻底避免重复写HTML:
第一步:定义商品数据
const products = [ { name: 'log', price: 2.23 }, { name: 'leaf', price: 0.28 }, { name: 'stone', price: 0.14 }, { name: 'melon', price: 2.80 } ];
第二步:动态生成HTML结构
const table = document.querySelector('table'); // 生成价格行 const priceRow = document.createElement('tr'); products.forEach(prod => { const td = document.createElement('td'); td.dataset.product = prod.name; td.innerHTML = ` <span class="price">${prod.price.toFixed(2)}</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> `; priceRow.appendChild(td); }); table.appendChild(priceRow); // 生成数量选择器行 const quantityRow = document.createElement('tr'); quantityRow.id = 'quantity-container'; products.forEach(prod => { const td = document.createElement('td'); td.dataset.product = prod.name; td.innerHTML = ` <input type="button" value="-" class="quantity-btn" data-action="decrease"> <input type="number" class="quantity-input" value="0" min="0"> <input type="button" value="+" class="quantity-btn" data-action="increase"> <br> Total: <span class="total">0.00</span> <img src="ShopStuff/gold_coin.png" style="width:20px; height:20px;"> `; quantityRow.appendChild(td); }); table.appendChild(quantityRow);
最后复用上面的事件委托JavaScript代码即可,新增商品只需修改products数组,无需重复编写HTML结构。
核心思路
- 用类选择器替代唯一ID,避免硬编码;
- 用数据属性关联商品信息,让代码动态识别不同商品;
- 用事件委托监听父容器,减少事件绑定数量;
- 封装通用逻辑或模板,新增商品只需添加数据,无需重复写结构。
内容的提问来源于stack exchange,提问作者Spleefies
相关产品推荐
相关产品推荐

