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块循环逻辑存在严重缺陷:
- 遍历购物车时,每遇到一个不匹配的商品就执行一次
cart.push(product),导致同一个商品被多次添加,数量被无规律放大; - 找到匹配商品后未终止循环,后续仍会继续执行判断,引发错误操作。
修复后的代码
替换原点击事件的逻辑部分:
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
相关产品推荐
相关产品推荐

