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

JavaScript购物车:添加新商品时输入元素计数器值重置问题修复

问题描述

我一直在调试以下代码,但始终无法达到预期效果:

现有JS代码

var milo = document.getElementById('milo');
var ovaltine = document.getElementById('ovaltine');
var bournvita = document.getElementById('bournvita');

var miloPrice = 2000.00;
var ovaltinePrice = 1500.00;
var bournvitaPrice = 1850.00;

var milocounter = 0;
var miloAmount = 0;

var ovaltinecounter = 0;
var ovaltineAmount;

var bournvitacounter = 0;
var bournvitaAmount = 0;

milo.addEventListener('click', function(){

    if (milocounter == 0) {
        milocounter += 1;
        miloAmount = miloPrice * milocounter;

        cartdetails.innerHTML += '<tr>' +
            '<td><input type="text" id="formilocounter" value="' + milocounter +'"></td>' +
            '<td><input type="text" id="formiloamount" value="' + miloAmount +'"></td>' +
            '</tr>' + '<br>';

    }

    else {
        milocounter += 1;
        miloAmount = miloPrice * milocounter;
        

        var formilocounter = document.getElementById('formilocounter');
        var formiloamount = document.getElementById('formiloamount');

        formilocounter.value = milocounter;
        formiloamount.value = miloAmount;
        
    }    
});

ovaltine.addEventListener('click', function(){

    if (ovaltinecounter == 0) {
        ovaltinecounter += 1;
        ovaltineAmount = ovaltinePrice * ovaltinecounter;


        cartdetails.innerHTML += '<tr>' +
            '<td><input type="text"  id="forovaltinecounter" value="' + ovaltinecounter +'"></td>' +
            '<td><input type="text" id="forovaltineamount" value="' + ovaltineAmount +'"></td>' +
            '</tr>' + '<br>';
    }

    else {
        ovaltinecounter += 1;
        ovaltineAmount = ovaltinePrice * ovaltinecounter;

       

        var forovaltinecounter = document.getElementById('forovaltinecounter');
        var forovaltineamount = document.getElementById('forovaltineamount');

        forovaltinecounter.value = ovaltinecounter;
        forovaltineamount.value = ovaltineAmount;

    }
});

bournvita.addEventListener('click', function(){
 

    if (bournvitacounter == 0) {
        bournvitacounter += 1;
        bournvitaAmount = bournvitaPrice * bournvitacounter;

        cartdetails.innerHTML += '<tr>' +

            '<td ><input type="text" id="forbournvitacounter" value="' + bournvitacounter +'"></td>' +
            '<td ><input type="text" id="forbournvitaamount" value="' + bournvitaAmount +'"></td>' +
            '</tr>' + '<br>';

    }

    else {
        bournvitacounter += 1;
        bournvitaAmount = bournvitaPrice * bournvitacounter;

        var forbournvitacounter = document.getElementById('forbournvitacounter');
        var forbournvitaamount = document.getElementById('forbournvitaamount');

        forbournvitacounter.value = bournvitacounter;
        forbournvitaamount.value = bournvitaAmount;
    }

});

现有HTML代码

<article>
    <div id="milo" >
        <img src="images/milo.jfif"><br>
        <label>2,000.00</label>
    </div>
    
    <div id="ovaltine">
        <img src="images/ovaltine.jfif"><br>
        <label >1,500.00</label>
    </div>
    
    <div id="bournvita">
        <img src="images/bournvita.jfif"><br>
        <label>1,850.00</label>
    </div>
</article>

 <div id="cartdetails">

 </div>

当前异常表现

点击任意商品首次添加及重复点击同一件商品时,功能正常;但点击另一件新商品时,之前已添加商品的输入框计数器会被重置为1,再次点击该商品时又会恢复正确计数。需要实现添加新商品时,所有已添加商品的计数器值保持不变。


解决方案

问题根源

使用cartdetails.innerHTML += ...拼接HTML时,浏览器会重新解析整个容器内的DOM结构,已存在的输入框会被重新创建,导致它们的value丢失,变回初始的1。

修改后的代码

JS代码

// 统一管理商品数据,减少重复逻辑
const products = [
    { id: 'milo', price: 2000.00, counter: 0, row: null },
    { id: 'ovaltine', price: 1500.00, counter: 0, row: null },
    { id: 'bournvita', price: 1850.00, counter: 0, row: null }
];

const cartDetails = document.getElementById('cartdetails');

// 为每个商品绑定点击事件
products.forEach(product => {
    const el = document.getElementById(product.id);
    el.addEventListener('click', () => {
        product.counter += 1;
        const amount = product.price * product.counter;

        if (!product.row) {
            // 首次添加,动态创建DOM元素
            const tr = document.createElement('tr');
            
            // 创建计数器输入框
            const counterTd = document.createElement('td');
            const counterInput = document.createElement('input');
            counterInput.type = 'text';
            counterInput.value = product.counter;
            counterTd.appendChild(counterInput);
            
            // 创建金额输入框
            const amountTd = document.createElement('td');
            const amountInput = document.createElement('input');
            amountInput.type = 'text';
            amountInput.value = amount;
            amountTd.appendChild(amountInput);
            
            tr.appendChild(counterTd);
            tr.appendChild(amountTd);
            
            // 保存DOM引用,方便后续更新
            product.row = tr;
            product.counterInput = counterInput;
            product.amountInput = amountInput;
            
            // 添加到购物车容器
            cartDetails.appendChild(tr);
            cartDetails.appendChild(document.createElement('br'));
        } else {
            // 更新已有商品的计数和金额
            product.counterInput.value = product.counter;
            product.amountInput.value = amount;
        }
    });
});

HTML代码(无需改动)

<article>
    <div id="milo" >
        <img src="images/milo.jfif"><br>
        <label>2,000.00</label>
    </div>
    
    <div id="ovaltine">
        <img src="images/ovaltine.jfif"><br>
        <label >1,500.00</label>
    </div>
    
    <div id="bournvita">
        <img src="images/bournvita.jfif"><br>
        <label>1,850.00</label>
    </div>
</article>

<div id="cartdetails"></div>

改动说明

  1. 统一商品数据管理:将所有商品的ID、价格、计数器、DOM引用整合到数组中,避免重复代码,后续扩展商品更便捷。
  2. 动态创建DOM:使用document.createElement生成元素并添加到容器,不会破坏已有的DOM节点,原有输入框的数值不会丢失。
  3. 保存DOM引用:首次创建元素后,将其存入商品对象,后续点击时直接更新元素值,无需再次查找DOM,提升性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 01:24:51