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

JavaScript中number类型input结合addEventListener购物车数量异常问题

电商购物车localStorage存储异常问题

我是JavaScript新手,这个问题已经困扰我10天了。我正在开发一个售卖沙发的电商网站购物车,要求仅通过localStorage存储数据:当购物车中已存在相同名称和颜色的沙发时,再次添加应只增加数量,而非新增条目。

产品页面包含颜色选择下拉框和number类型的数量输入框。测试发现第一个添加的商品数量累加正常,但添加其他商品(或同商品不同颜色)后出现两个异常:

  • 输入的数量会被无规律放大(翻倍、四倍等);
  • 无论是否为同商品同颜色,都会在购物车数组中新增条目。

相关代码

HTML代码

<article>
  <div class="item__img">
    <!-- <img src="../images/logo.png" alt="Photographie d'un canapé"> -->
  </div>
  <div class="item__content">

    <div class="item__content__titlePrice">
      <h1 id="title"><!-- Nom du produit --></h1>
      <p>Prix : <span id="price"><!-- 42 --></span>€</p>
    </div>

    <div class="item__content__description">
      <p class="item__content__description__title">Description :</p>
      <p id="description"><!-- Dis enim malesuada risus sapien gravida nulla nisl arcu. --></p>
    </div>

    <div class="item__content__settings">
      <div class="item__content__settings__color">
        <label for="colors">Choisir une couleur :</label>
        <select name="color-select" id="colors">
          <option value="" disabled selected >--SVP, choisissez une couleur --</option>
          <!-- <option value="vert">vert</option>
          <option value="blanc">blanc</option> -->
        </select>
      </div>

      <div class="item__content__settings__quantity">
        <label for="quantity">Nombre d'article(s) (1-100) :</label>
        <input type="number" name="itemQuantity" min="1" max="100" value="1" id="quantity">
      </div>
    </div>

    <div class="item__content__addButton">
      <button id="addToCart">Ajouter au panier</button>
    </div>
  </div>
</article>

JavaScript代码

// 定义localStorage中购物车的存储与读取函数
function saveCart(cart){
  localStorage.setItem("cart", JSON.stringify(cart));
}

function getCart(){
  let cart= localStorage.getItem("cart");
  if (cart==null){
    return [];
  }else{
    return JSON.parse(cart);
  } 
}

// 测试用:清空localStorage中的购物车
function deleteCart(){
  localStorage.removeItem("cart");
}

// 加入购物车按钮点击事件
const boutonAddToCart= document.querySelector("#addToCart");
const productQuantity=document.querySelector("#quantity");
boutonAddToCart.addEventListener('click', function() {
  
  let product= {
    // id: item._id,
    name:item.name,
    qty:parseInt(productQuantity.value,10),
    color:document.getElementById("colors").value
  };
  // deleteCart();
  
  console.log(product);
  
  let cart=getCart();  
  console.log(cart);
  
  if (cart.length===0){
    cart.push(product);
  }
  
  else{
    for (let i=0; i<cart.length; i++){
      console.log(cart[i]);
      
      if (cart[i].name===product.name && cart[i].color===product.color ){ 
        cart[i].qty+=product.qty;
      }
      else {
        cart.push(product);
      }
    }
    
    console.log(localStorage);
  }
  saveCart(cart);
  
});

问题分析与修复

核心问题

原代码的else块循环逻辑存在严重缺陷:

  1. 遍历购物车时,每遇到一个不匹配的商品就执行一次cart.push(product),导致同一个商品被多次添加,数量被无规律放大;
  2. 找到匹配商品后未终止循环,后续仍会继续执行判断,引发错误操作。

修复后的代码

替换原点击事件的逻辑部分:

const boutonAddToCart = document.querySelector("#addToCart");
const productQuantity = document.querySelector("#quantity");
boutonAddToCart.addEventListener('click', function() {
  
  // 校验颜色是否选择
  const selectedColor = document.getElementById("colors").value;
  if (!selectedColor) {
    alert("请先选择商品颜色");
    return;
  }

  let product = {
    name: item.name,
    qty: parseInt(productQuantity.value, 10),
    color: selectedColor
  };

  let cart = getCart();
  let isProductExist = false;

  // 遍历购物车查找匹配商品
  for (let i = 0; i < cart.length; i++) {
    const cartItem = cart[i];
    if (cartItem.name === product.name && cartItem.color === product.color) { 
      cartItem.qty += product.qty;
      isProductExist = true;
      // 找到匹配项后立即终止循环,避免多余操作
      break;
    }
  }

  // 未找到匹配项则添加新商品
  if (!isProductExist) {
    cart.push(product);
  }

  saveCart(cart);
  console.log("购物车已更新:", cart);
});

额外优化建议

  • 保留商品id字段:仅靠名称和颜色判断可能存在冲突(比如不同商品同名同色),使用商品唯一ID作为判断依据更可靠;
  • 数量输入校验:确保输入值在1-100范围内,避免非法数值存入;
  • 操作反馈:添加成功提示,提升用户体验。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 13:17:55