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

如何在纯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判断购物车内商品是否重复,以此区分同款不同克重的商品。

具体实现步骤

  1. 生成唯一商品标识
    点击购买按钮时,同时获取商品ID和用户选择的克重值,组合成唯一标识(比如商品ID_克重,例:prod001_250、prod001_500)。

  2. 修改购物车匹配逻辑

    • 新增商品时,用这个唯一标识查找购物车内是否已有对应条目,而非仅用商品ID。
    • 购物车DOM元素的data-cart-pid属性存储这个唯一标识,确保删除、增减数量时能精准定位对应规格的商品。
  3. 调整现有代码关键部分

    • 购买按钮点击事件补充获取克重:
      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设为该唯一标识。
  4. 数据持久化优化(可选)
    若用localStorage保存购物车数据,每条数据需包含productId、weight、quantity、price等完整信息,方便后续恢复和计算。

额外注意点

  • 确保克重选择控件的值合法有效,避免空值或异常值导致唯一标识错误。
  • 购物车条目需明确显示克重信息,让用户清晰区分不同规格的同款商品。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 14:46:07