购物车数量显示异常:删除商品时数量直接归零而非递减
购物车数量显示异常问题
问题描述
商品添加到购物车时数量显示正常(例如添加5件后数值正确),但点击垃圾桶图标移除商品时,数量并未递减1,而是直接变为0。
相关代码
let cartQuantityNr = 0; let cartQuantitySpan = document.querySelector(".cart-quantity"); let cartQuantitySpanHome = document.querySelector(".cartQuantity"); // Removing item from cart const removeCartItem = () => { let removeCartItemBtn = document.querySelectorAll(".cart .rm-item"); removeCartItemBtn.forEach(e => { e.addEventListener("click", () => { e.parentElement.parentElement.remove(); cartQuantityNr--; console.log(cartQuantityNr); cartQuantitySpan.innerHTML = "(" + cartQuantityNr + ")"; cartQuantitySpanHome.innerHTML = cartQuantityNr; }) }) } // Quantity spans const quantitySpans = () => { cartQuantityNr++; cartQuantitySpan.innerHTML = "(" + cartQuantityNr + ")"; cartQuantitySpanHome.innerHTML = cartQuantityNr; }
相关截图



问题原因
- 重复绑定点击事件:每次添加商品后若调用
removeCartItem,会给所有已存在的删除按钮重复绑定点击事件。比如添加5件商品后,每个删除按钮被绑定5次点击逻辑,点击一次就会执行5次cartQuantityNr--,直接从5变为0。 - 变量与实际数量不同步:仅依赖
cartQuantityNr自增自减维护数量,未和购物车实际商品数量挂钩,一旦事件绑定异常就会出现数值偏差。
解决方案
方案1:事件委托(推荐)
将点击事件绑定到购物车父容器上,无需给每个按钮单独绑定,动态生成的按钮也能触发,且仅需绑定一次:
let cartQuantityNr = 0; let cartQuantitySpan = document.querySelector(".cart-quantity"); let cartQuantitySpanHome = document.querySelector(".cartQuantity"); const cartContainer = document.querySelector(".cart"); // 事件委托处理删除逻辑 cartContainer.addEventListener("click", (e) => { if (e.target.classList.contains("rm-item")) { e.target.parentElement.parentElement.remove(); // 直接统计购物车剩余商品数量,确保数值准确 cartQuantityNr = document.querySelectorAll(".cart .cart-item").length; cartQuantitySpan.innerHTML = `(${cartQuantityNr})`; cartQuantitySpanHome.innerHTML = cartQuantityNr; } }); // 添加商品更新数量 const quantitySpans = () => { // 同样统计实际商品数量,避免变量出错 cartQuantityNr = document.querySelectorAll(".cart .cart-item").length; cartQuantitySpan.innerHTML = `(${cartQuantityNr})`; cartQuantitySpanHome.innerHTML = cartQuantityNr; }
方案2:避免重复绑定事件
如果坚持给单个按钮绑定事件,需在生成商品元素时直接绑定,而非重复调用removeCartItem:
// 示例:添加商品的函数中绑定删除事件 const addToCart = (itemInfo) => { // 创建商品DOM元素... const removeBtn = document.createElement("button"); removeBtn.classList.add("rm-item"); removeBtn.textContent = "删除"; // 直接给当前按钮绑定一次删除逻辑 removeBtn.addEventListener("click", () => { removeBtn.parentElement.parentElement.remove(); cartQuantityNr--; cartQuantitySpan.innerHTML = `(${cartQuantityNr})`; cartQuantitySpanHome.innerHTML = cartQuantityNr; }); // 将按钮添加到商品元素中... } // 添加商品更新数量 const quantitySpans = () => { cartQuantityNr++; cartQuantitySpan.innerHTML = `(${cartQuantityNr})`; cartQuantitySpanHome.innerHTML = cartQuantityNr; }
关键提示
优先使用事件委托,它能解决动态元素的事件绑定问题,同时避免重复绑定导致的多次执行bug。此外,通过统计购物车实际商品数量更新显示值,比单纯依赖变量自增自减更可靠,能保证数值和实际商品数量始终一致。
内容的提问来源于stack exchange,提问作者lis3q
相关产品推荐
相关产品推荐

