如何在纯JS购物车中添加同ID不同参数的商品?
购物车实现问题:同款不同克重商品的处理逻辑
我正在用纯JavaScript开发购物车功能。点击购买按钮时,我会获取商品ID并将同ID商品加入购物车。但该商品支持克重选择,用户可添加250克和500克的同款商品,问题在于该商品共用一个ID。请告知此类购物车的大致实现逻辑。
现有实现代码
window.addEventListener('load', ()=> { const cart = document.querySelector('.cart-header__icon') const buyButtons = document.querySelectorAll('.item-product__buy'); const deleteButtons = document.querySelectorAll('.item-cart__delete'); buyButtons.forEach(buyButton => { buyButton.addEventListener('click', () => { const productId = buyButton.closest('.item-product').dataset.pid; addToCart(buyButton, productId) }) }) deleteButtons.forEach(deleteButton => { deleteButton.addEventListener('click', () => { const productId = deleteButton.closest('.item-cart').dataset.cartPid; updateCart(deleteButton, productId, false) }) }) function addToCart(productButton, productId) { if(!productButton.classList.contains('_hold')) { productButton.classList.add('_hold'); productButton.classList.add('_fly'); const product = document.querySelector(`[data-pid="${productId}"]`); const productImage = document.querySelector('.item-product__image'); const productImageFly = productImage.cloneNode(true); const productImageFlyWidth = productImage.offsetWidth; const productImageFlyHeight = productImage.offsetHeight; const productImageFlyTop = productImage.getBoundingClientRect().top; const productImageFlyLeft = productImage.getBoundingClientRect().left; productImageFly.setAttribute('class', '_flyImage _ibg'); productImageFly.style.cssText = ` left: ${productImageFlyLeft}px; top: ${productImageFlyTop}px; width: ${productImageFlyWidth}px; height: ${productImageFlyHeight}px; `; document.body.append(productImageFly); const cartFlyLeft = cart.getBoundingClientRect().left; const cartFlyTop = cart.getBoundingClientRect().top; productImageFly.style.cssText = ` left: ${cartFlyLeft}px; top: ${cartFlyTop}px; width: 0px; height: 0px; opacity: 0; `; productImageFly.addEventListener('transitionend', () => { if (productButton.classList.contains('_fly')) { productImageFly.remove() updateCart(productButton, productId); productButton.classList.remove('_fly') } }) } } function updateCart(productButton, productId, productAdd = true) { const cart = document.querySelector('.cart-header'); const cartIcon = cart.querySelector('.cart-header__icon'); const cartQuantity = cartIcon.querySelector('.icon-header__number'); const cartProduct = document.querySelector(`[data-cart-pid="${productId}"`); const cartList = document.querySelector('.cart-header__list'); if (productAdd) { if (cartQuantity) { cartQuantity.innerHTML = ++cartQuantity.innerHTML; } else { cartIcon.insertAdjacentHTML('beforeend', `<span class="icon-header__number">1</span>`); } if (!cartProduct) { const product = document.querySelector(`[data-pid="${productId}"]`); const cartProductImage = product.querySelector('.item-product__image').innerHTML; const cartProductTitle = product.querySelector('.item-product__name').innerHTML; const cartProductWeigh = product.querySelector('.item-product__weigh-input').value; const cartProductPrice = product.querySelector('.item-product__current-price span').innerHTML const cartProductContent = ` <a href="" class="item-cart__image _ibg"> ${cartProductImage} </a> <div class="item-cart__content"> <div class="item-cart__info"> <a href="" class="item-cart__title"> <span class="item-cart__name">${cartProductTitle}</span>, <span class="item-cart__weigh">${cartProductWeigh}г</span> </a> </div> <div class="item-cart__quantity"> <button type="button" class="item-cart__button item-cart__button_minus">-</button> <div class="item-cart__input"> <span>1</span> </div> <button type="button" class="item-cart__button item-cart__button_plus">+</button> </div> </div> <div class="item-cart__control"> <div class="item-cart__price"> <span>${cartProductPrice}</span>грн </div> <div class="item-cart__delete"> <span> <svg fill="none" height="28" viewBox="0 0 28 28" width="28" xmlns="http://www.w3.org/2000/svg"> <path d="M2.32129 2.32363C2.72582 1.9191 3.38168 1.9191 3.78621 2.32363L25.6966 24.234C26.1011 24.6385 26.1011 25.2944 25.6966 25.6989C25.2921 26.1035 24.6362 26.1035 24.2317 25.6989L2.32129 3.78854C1.91676 3.38402 1.91676 2.72815 2.32129 2.32363Z" fill="black"></path> <path d="M25.6787 2.30339C25.2742 1.89887 24.6183 1.89887 24.2138 2.30339L2.30339 24.2138C1.89887 24.6183 1.89887 25.2742 2.30339 25.6787C2.70792 26.0832 3.36379 26.0832 3.76831 25.6787L25.6787 3.76831C26.0832 3.36379 26.0832 2.70792 25.6787 2.30339Z" fill="black"></path> </svg> </span> </div> </div> ` cartList.insertAdjacentHTML('beforeend',`<li data-cart-pid="${productId}" class="cart-header__item item-cart">${cartProductContent}</li>`) } else { const cartProductQuantity = cartProduct.querySelector('.item-cart__input span'); cartProductQuantity.innerHTML = ++cartProductQuantity.innerHTML; } } else { const cartProductQuantity = cartProduct.querySelector('.item-cart__input span'); cartProductQuantity.innerHTML = --cartProductQuantity.innerHTML; if(!parseInt(cartProductQuantity.innerHTML)) { cartProduct.remove() } } productButton.classList.remove('_hold') } })
同款不同克重商品的购物车实现逻辑
核心思路
用**「商品ID+克重规格」**作为唯一区分键,不再单独依赖商品ID判断购物车内商品是否重复,以此区分同款不同克重的商品。
具体实现步骤
生成唯一商品标识
点击购买按钮时,同时获取商品ID和用户选择的克重值,组合成唯一标识(比如商品ID_克重,例:prod001_250、prod001_500)。修改购物车匹配逻辑
- 新增商品时,用这个唯一标识查找购物车内是否已有对应条目,而非仅用商品ID。
- 购物车DOM元素的
data-cart-pid属性存储这个唯一标识,确保删除、增减数量时能精准定位对应规格的商品。
调整现有代码关键部分
- 购买按钮点击事件补充获取克重:
buyButton.addEventListener('click', () => { const product = buyButton.closest('.item-product'); const productId = product.dataset.pid; const selectedWeight = product.querySelector('.item-product__weigh-input').value; const uniqueKey = `${productId}_${selectedWeight}`; addToCart(buyButton, uniqueKey); }) - 改造
updateCart函数,用uniqueKey作为查找购物车条目的依据,创建条目时将data-cart-pid设为该唯一标识。
- 购买按钮点击事件补充获取克重:
数据持久化优化(可选)
若用localStorage保存购物车数据,每条数据需包含productId、weight、quantity、price等完整信息,方便后续恢复和计算。
额外注意点
- 确保克重选择控件的值合法有效,避免空值或异常值导致唯一标识错误。
- 购物车条目需明确显示克重信息,让用户清晰区分不同规格的同款商品。
内容的提问来源于stack exchange,提问作者Default
相关产品推荐
相关产品推荐

