如何使用原生JavaScript为披萨配送网站实现按尺寸区分的单品定价功能
解决方案:为披萨配送网站实现可复用的尺寸定价逻辑
看起来你已经有了基础的实现,但想要让代码更可复用、更易维护——尤其是当你有多个不同定价的披萨卡片时对吧?我来帮你优化一下这个逻辑,让每个披萨都能独立配置尺寸价格,同时避免冗余代码:
第一步:修改HTML结构,为每个披萨配置独立价格
我们可以通过自定义data-*属性,把每个披萨的尺寸价格直接存在对应的卡片里,这样新增或修改披萨价格时,不用改动JS代码:
<!-- 四季披萨 --> <div class="card" data-small-price="12" data-medium-price="16" data-large-price="20"> <div class="productInCart"> <img src="/images/picca/4-seasons.png" width="250px" alt="Four seasons pizza"> <h3 class="title">Four seasons</h3> <p class="description"> Bacon, Ham, Mushrooms, Chicken, Onion, Olives, Pickled Cucumbers, Hunting sausages, Pepperoni </p> <div class="picca_size"> <label data-size="small" class="btnActive active">20sm</label> <label data-size="medium" class="btnActive">28sm</label> <label data-size="large" class="btnActive">33sm</label> </div> <div class="wrapperPrice"> <p class="price">$<span>12</span></p> <button class="button-30 addToCart" role="button" data-product-id="1"> add to cart </button> </div> </div> </div> <!-- 玛格丽特披萨(不同定价) --> <div class="card" data-small-price="10" data-medium-price="14" data-large-price="18"> <div class="productInCart"> <img src="/images/picca/margherita.png" width="250px" alt="Margherita pizza"> <h3 class="title">Margherita</h3> <p class="description"> Tomato Sauce, Mozzarella, Basil, Olive Oil </p> <div class="picca_size"> <label data-size="small" class="btnActive active">20sm</label> <label data-size="medium" class="btnActive">28sm</label> <label data-size="large" class="btnActive">33sm</label> </div> <div class="wrapperPrice"> <p class="price">$<span>10</span></p> <button class="button-30 addToCart" role="button" data-product-id="2"> add to cart </button> </div> </div> </div>
这里给默认选中的尺寸按钮加上了active类,同时初始化了价格显示,避免页面加载时出现$0的问题。
第二步:优化JavaScript逻辑,实现通用的尺寸切换与价格展示
我们可以简化事件处理逻辑,让它不再依赖硬编码的价格,而是从卡片的data-*属性中动态读取:
// 处理尺寸按钮点击事件 window.addEventListener('click', function(event) { // 精准定位点击的尺寸按钮 const sizeButton = event.target.closest('[data-size].btnActive'); if (!sizeButton) return; const cardWrapper = sizeButton.closest('.card'); const selectedSize = sizeButton.dataset.size; const priceElement = cardWrapper.querySelector('.price span'); // 移除当前卡片所有尺寸按钮的active状态 cardWrapper.querySelectorAll('.btnActive').forEach(btn => btn.classList.remove('active')); // 标记当前点击的按钮为活跃状态 sizeButton.classList.add('active'); // 从卡片的data属性中获取对应尺寸的价格 const targetPrice = cardWrapper.dataset[`${selectedSize}Price`]; priceElement.textContent = targetPrice; }); // 页面加载完成后初始化所有卡片的默认价格 document.addEventListener('DOMContentLoaded', function() { document.querySelectorAll('.card').forEach(card => { const activeBtn = card.querySelector('.btnActive.active'); if (activeBtn) { const defaultSize = activeBtn.dataset.size; const defaultPrice = card.dataset[`${defaultSize}Price`]; card.querySelector('.price span').textContent = defaultPrice; } }); });
为什么这样优化更好?
- 数据与逻辑分离:每个披萨的价格配置都在HTML里,新增或修改披萨时,不用动JS代码,维护成本更低。
- 代码更简洁:用批量操作替代了逐个移除类名的重复代码,去掉了冗余的if-else分支。
- 扩展性更强:如果以后要新增披萨尺寸(比如超大号),只需在HTML里加对应的按钮和
data-xxx-price属性,JS代码完全不用改。 - 初始化更合理:页面加载时自动显示默认尺寸的正确价格,不会出现初始显示$0的问题。
内容的提问来源于stack exchange,提问作者Mr Dot
相关产品推荐
相关产品推荐

