Js for循环和监听事件一起运用出现问题

Js for循环和监听事件一起运用的问题(问题已解决)
用for循环给每一个button加监听事件,点击按钮最后都是一样的结果,是异步的问题吗?这个问题要怎么才能解决

img

代码我都放出来了
* {
            margin: 0;
            padding: 0;
        }
        body {
            font-size: 0;
            background-color: rgb(240, 240, 240);
        }
        #index {
            width: 100%;
            background-color: #ffffff;
            border-bottom: 2px solid red;
            height: 55px;
            line-height: 50px;
            position: fixed;
            box-shadow: 1px 1px 1px rgb(178, 175, 175);
            z-index: 99;
            margin: 0 auto;
        }
        #pack {
            width: 1290px;
            height: 50px;
            margin: 0 auto;
            text-align: left;
            font-size: 18px;
        }
        #pack :hover {
            color: red;
        }
        .sousuo {
            width: 400px;
            height: 20px;
            border: 2px solid rgb(226, 2, 2);
            /* position: relative;
            left: 30%; */
            border-radius: 4px;
            margin-left: 10px;
        }
        #index :nth-child(2) {
            cursor: pointer;
            margin: 3px;
        }
        #index a {
            cursor: pointer;
            margin-left: 540px;
            text-decoration: none;
            color: black;
        }
        #index :nth-child(4) {
            cursor: pointer;
            margin-left: 30px;
        }
        #index :nth-child(5) {
            cursor: pointer;
            
            /* background-color: antiquewhite; */
            display: inline-block;
            height: 57px;
            width: 100px;
            padding-left: 30px;
        }
        #shop {
            margin: 0 auto;
            width: 1180px;
            height:500px;
            background-color: rgb(255, 255, 255); 
            /* z-index:3;  */
            /* left:800px; */
            font-size:16px;
            top:70px;
            position: relative;
            border: 2px solid red;
            border-radius:20px;
        }
        #shop table {
            /* padding-top: 30px; */
            margin: 0 auto;
            position: relative;
            top: 10px;
        }
        #shop .dle{
            cursor: pointer;
        }
        #shop #footer2  {
            text-align: center;
            font-weight: bold;
        }
        #footer1 {
            text-align: center;
            font-weight: bold;
        }
        #box {
            margin: 0 auto;
            width: 1180px;
            margin-top: 80px;
            margin-bottom: 5px;
            /* background-color: rgb(175, 114, 35); */
        }
        #box div {
            width: 232px;
            height: 295px;
            background-color: rgba(255, 255, 255);
            display: inline-block;
            margin-right: 5px;
            margin-top: 5px;
            text-align: center;
            vertical-align: middle;
            position: relative;
            overflow: hidden;
            /* display: flexbox; */
            
        }
        #box div img {
            width: 160px;
            height: 160px;
            margin-top: 27px;
        }
        #box div p {
            padding-top: 20px;
            font-size: 16px;
            width: 80%;
            height: 40px;
            overflow: hidden; 
            display: -webkit-box;
            -webkit-line-clamp: 2;
            -webkit-box-orient: vertical;
            word-break: break-all;
            margin: 0 auto;
        }
        #box div button :hover {
            background-color: rgb(189, 67, 67);  
            font-weight: bold;          
        }
        #footer {
            width: 100%;
            height: 100px;
            background-color: white;
            font-size: 16px;
            text-align: center;
            border-top: 2px solid red;
            box-shadow: 0px -1px 1px rgb(178, 175, 175);
            box-sizing: border-box;
        }

<div id="index">
        <div id="pack">
            <input type="text" class="sousuo" placeholder="连花清瘟胶囊">
            <span>搜索</span>
            <a href="logon.html">登录</a>
            <span>我的收藏</span>
            <!-- <span>历史记录</span> -->
            <span id="buycar">我的购物车</span>
        </div>
    </div>

    <div id="shop">
        <table id="table" border = 1>
            <tr>
                <th style="width: 330px;">商品名</th>
                <th style="width: 130px;">价格</th>
                <th style="width: 150px;">数量</th>
                <th style="width: 100px;">操作</th>
            </tr>
            <!-- <tr id="footer2">
                <td colspan="2" id="clear">清空购物车</td>
                <td colspan="2" id="jie">结算</td>
            </tr>
            <tr id="footer1">
                <td colspan="2">总额¥:</td>
                <td colspan="2" id="sum"></td>
            </tr> -->
        </table>
    </div>

    <div id ="footer">
        <p>wdakwjdailkwdijn</p>
    </div>


//动态添加商品
        var arrdata = [
            {img:'image/1.jpg',desc:'三星 SAMSUNG Galaxy Z Fold3 5G 屏下摄像折叠屏 双模5G手机 Spen书写 IPX8防水 12GB+512GB陨石黑',shijia:'¥8999.00',jiage:'¥8969.00'},
            {img:'image/2.jpg',desc:'飞利浦(PHILIPS)车载空气净化器 汽车新车除味除甲醛甲苯除PM2.5 瓦解病毒GP5202',shijia:'¥349.00',jiage:'¥349.00'},
            {img:'image/3.jpg',desc:'三顿半 数字星球系列1-6号混合装 美式黑咖啡速溶冻干咖啡粉桶装80颗*3g',shijia:'¥599.00 ',jiage:'¥599.00 '},
            {img:'image/4.jpg',desc:'联想笔记本电脑k4e 14英寸锐龙pro旗舰版高端超轻薄本设计师商用办公学生超极手提本 六核新锐R5 16G内存 512G固态 带office丨升级 满血游戏级显卡 FHD全高清屏 支持双硬盘 金属',shijia:'¥4399.00',jiage:'¥4099.00'},
            {img:'image/5.jpg',desc:'科大讯飞录音降噪会议耳机iFLYBUDS Pro 无线蓝牙耳机 主动降噪 入耳式 超长续航 录音转文字 苹果华为通用',shijia:'¥999.00',jiage:'¥849.00'},
            {img:'image/6.jpg',desc:'霍尼韦尔(Honeywell )JQJCY01YM甲醛检测仪小米检测仪空气质量检测仪家用车内房车米家智能测甲醛仪器',shijia:'¥399.00',jiage:'¥349.00'},
            {img:'image/7.jpg',desc:'创维(Skyworth)28英寸 4K显示器 IPS 10.7亿色 HDR技术 Type-C+手机投屏 升降底座 电脑高清HDMI(28U1)',shijia:'¥1499.00',jiage:'¥1299.00'},
            {img:'image/8.jpg',desc:'蒙牛 特仑苏脱脂纯牛奶 每100ml含3.6g乳蛋白 送礼推荐 250ml×16 礼盒装 送礼佳品',shijia:'¥68.00',jiage:'¥58.00'},
            {img:'image/9.jpg',desc:'脉动青柠口味 400ML*15瓶 迷你便携小瓶维C果汁水低糖维生素运动饮料',shijia:'¥55.90',jiage:'¥45.90'},
            {img:'image/10.jpg',desc:'雷柏(Rapoo) E9300G 无线键盘 蓝牙键盘 办公键盘 超薄便携键盘 98键 电脑键盘 平板ipad键盘 白色',shijia:'¥139.00',jiage:'¥119.00'}
        ];
        var wrap = document.createElement('div');
        wrap.setAttribute('id','box')
        var length =Math.ceil(arrdata.length/5) * 300;
        // console.log(length);
        wrap.style.height = length; 
        var footer = document.getElementById('footer');
        footer.parentElement.insertBefore(wrap,footer)

        var box = document.getElementById('box');
        for(var i = 0; i < arrdata.length;i++) {
            var div = document.createElement('div');
            div.setAttribute('class','test1')
            if((i+1) % 5 == 0 ) {   
                // console.log('success')
                div.style.marginRight = '0px';
                // div.setAttribute('class','test1') 
            }
            div.innerHTML = `<img src=${arrdata[i].img} style = "z-index:1; position:relative;">
            <p style = "z-index:1; position:relative;">${arrdata[i].desc}</p>
            <button class="button">添加至购物车</button>
            `
            box.appendChild(div)            
        }
        //添加至购物车
        for(var i in arrdata) {
            var button = document.getElementsByClassName('button');
            
            console.log(table)
                // button[i].index = i;
                button[i].addEventListener('click',function() {
                var table = document.getElementsByTagName('table');
                console.log(table)
                var tr = document.createElement('tr');
                tr.innerHTML = `<td style = "width:330px; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; height:30px; line-height:30px">${arrdata[i].desc}</td>
                            <td style = "width:100px" class="danjia">${arrdata[i].jiage}</td>
                            <td style = "width:130px">
                            <button class="minus" style="width:30px; height:23px; font-size:16px">-</button>
                            <input class="inp2" value = 0 type="text" style = "width:30px; text-align:center; height:20px" >
                            <button class="add" style="width:30px; height:23px; font-size:16px">+</button>
                            </td>
                            <td style = "width:50px" class="delete">删除</td>`
                            console.log(tr)
                table[0].appendChild(tr)
            })
        }

解决办法(闭包可以解决问题)

问题一直出在i的身上,创建一个index保存i..这玩意给算不上一知半解的我碰到了简直就是噩梦
button[i].index = i;
${arrdata[this.index].desc}


for(var i in arrdata) {
            var button = document.getElementsByClassName('button');
                button[i].index = i;
                button[i].addEventListener('click',function() {                
                var table = document.getElementsByTagName('table');
                console.log(table)
                var tr = document.createElement('tr');
                tr.innerHTML = `<td style = "width:330px; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 1; -webkit-box-orient: vertical; height:30px; line-height:30px">${arrdata[this.index].desc}</td>
                            <td style = "width:100px" class="danjia">${arrdata[this.index].jiage}</td>
                            <td style = "width:130px">
                            <button class="minus" style="width:30px; height:23px; font-size:16px">-</button>
                            <input class="inp2" value = 0 type="text" style = "width:30px; text-align:center; height:20px" >
                            <button class="add" style="width:30px; height:23px; font-size:16px">+</button>
                            </td>
                            <td style = "width:50px" class="delete">删除</td>`
                            console.log(tr)
                table[0].appendChild(tr)
            })
        }

望采纳


在这段代码中,你使用了for循环来遍历所有的button,并为每一个button添加了点击事件监听。但是,在循环内部的监听事件函数中,使用的是相同的变量i来设置图片的src属性。

因此,当你点击任意一个button时,都会执行相同的监听事件函数,导致所有的button都会显示同一张图片。

你需要在监听事件函数中使用不同的变量,或者使用闭包的方式来保存变量的值。你可以将监听事件函数改写为如下形式:

for (var i = 0; i < lis.length; i++) {
  lis[i].onclick = (function (i) {
    return function () {
      img.src = 'img/' + i + '.jpg';
    }
  })(i);
}

这样,在监听事件函数内部就能访问到不同的变量i的值,从而正确地设置图片的src属性。