You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS购物车添加重复商品时仅累加数量不新增条目的实现问题

购物车重复商品逻辑修复方案

核心实现逻辑

  • 新增购物车状态对象存储已添加商品的数量、单价、对应DOM节点,避免重复DOM查询
  • 以商品标题作为唯一标识,新增前先匹配状态对象中是否存在对应商品
  • 匹配到重复商品仅更新数量与对应价格,未匹配到再新增条目
  • 删除逻辑同步适配数量规则,单次点击减少1份数量,数量归0再移除整条DOM

修改后的完整代码

<div class="pizzas">
</div>
<div class="shoppingCart">
    <p class="totalPrice">Hungry? order our pizzas</p>
</div>

<script>
fetch("https://raw.githubusercontent.com/alexsimkovich/patronage/main/api/data.json")
.then(data => data.json())
.then(data => {
    let valueCurrency = 0;
    // 新增购物车状态存储对象
    const cartItems = {};
    // 公共DOM查询提到循环外,减少性能消耗
    const shoppingCart = document.querySelector(".shoppingCart");
    const pizzas = document.querySelector(".pizzas");
    const totalPrice = document.querySelector(".totalPrice");

    data.forEach(element => {
        const box = document.createElement("div");
        const img = document.createElement("img");
        const title = document.createElement("h3");
        const ingredients = document.createElement("p");
        const price = document.createElement("h4");
        const btn = document.createElement("button");
         
        box.className = "box";
        ingredients.className = "ingredients"
        btn.className = "btn";
        img.src = element.image;
        img.className = "img";
         
        title.innerHTML = element.title;
        ingredients.innerHTML = element.ingredients;
        price.innerHTML = element.price.toFixed(2) + " zł";
        btn.innerHTML = "Dodaj do koszyka";
         
        box.appendChild(img);
        box.appendChild(title);
        box.appendChild(ingredients);
        box.appendChild(price);
        box.appendChild(btn);
        pizzas.appendChild(box);

        btn.addEventListener("click", (e) => {
            valueCurrency = valueCurrency + element.price;
            totalPrice.innerText = "Całkowita cena: " + valueCurrency.toFixed(2);
            const currentTitle = title.textContent;

            // 匹配已存在的商品
            if(cartItems[currentTitle]) {
                // 更新数量
                cartItems[currentTitle].count += 1;
                // 更新显示的数量和总价
                cartItems[currentTitle].titleEl.innerText = `${currentTitle} x ${cartItems[currentTitle].count}`;
                cartItems[currentTitle].priceEl.innerText = `${(element.price * cartItems[currentTitle].count).toFixed(2)} zł`;
                return;
            }

            // 不存在则新增条目
            const pizza = document.createElement("div");
            pizza.className = "pizzaList";
            const pizzasList = document.createElement("li");
            const pizzaPrice = document.createElement("p");
            const btnRemove = document.createElement("button");
            btnRemove.innerText = "X";
             
            pizzasList.innerText = `${currentTitle} x 1`;
            pizzaPrice.innerText = price.textContent;

            pizza.appendChild(pizzasList);
            pizza.appendChild(pizzaPrice);
            pizza.appendChild(btnRemove);
            shoppingCart.prepend(pizza);

            // 把新增的商品信息存入状态对象
            cartItems[currentTitle] = {
                count: 1,
                price: element.price,
                element: pizza,
                titleEl: pizzasList,
                priceEl: pizzaPrice
            }

            btnRemove.addEventListener("click", (e) => {
                valueCurrency = valueCurrency - element.price;
                totalPrice.innerText = "Całkowita cena: " + valueCurrency.toFixed(2);
                cartItems[currentTitle].count -= 1;

                if(cartItems[currentTitle].count > 0) {
                    // 数量大于0仅更新显示
                    cartItems[currentTitle].titleEl.innerText = `${currentTitle} x ${cartItems[currentTitle].count}`;
                    cartItems[currentTitle].priceEl.innerText = `${(element.price * cartItems[currentTitle].count).toFixed(2)} zł`;
                } else {
                    // 数量为0移除DOM和状态存储
                    pizza.remove();
                    delete cartItems[currentTitle];
                }
            })
        })
    });
})
.catch(err => console.log(err));
</script>

关键修改说明

  • 移除了原逻辑中无效的pizzasList.innerText === pizzasList.innerText判断,该判断左右为同一变量,永远返回true
  • 新增的cartItems对象会存储所有已添加商品的全量信息,无需每次新增前遍历DOM查询是否存在重复商品,性能更优
  • 商品条目会自动显示购买数量,单种商品的价格会随数量同步更新
  • 删除逻辑适配数量规则,不会误删多份商品的整个条目

内容的提问来源于stack exchange,提问作者ShockWave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 21:15:03