循环遍历加监听的问题

本文详细分析了在JavaScript中使用`var`声明变量导致的循环遍历事件监听问题,指出由于异步执行,点击按钮时获取的`i`值始终为循环结束后的值。并提出了三种解决方案:1) 为每个按钮添加独立的`index`属性;2) 使用立即执行函数创建局部作用域;3) 利用`let`声明块级作用域。这三种方法都能确保点击每个按钮时正确显示对应的`i`值。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 用var失败的原因

var btns = document.getElementsByTagName('button');
    for(var i = 0;i<btns.length;i++){
            btns[i].onclick = function () {
                alert(i);
            }
    }

点击监听事件是异步执行的,当点击按钮执行相应函数之前,同步任务(循环)已经执行结束,此时在全局作用域下的 i 已经为固定值。执行alert(i)时,沿着作用域链找到全局作用域下的 i ,导致点击每个按钮得到的结果相同。

2.  解决方法

2.1 添加属性

for(var i = 0;i<btns.length;i++){
            btns[i].index = i;
            btns[i].onclick = function () {
                alert(this.index);
            }
    }

原理:给每一个按钮绑定一个单独的属性,之后在执行点击监听的异步任务时,通过自己的属性来访问该值,不去访问全局作用域下的 i

2.2 立即执行函数

var btns = document.getElementsByTagName('button');
    for(var i = 0;i<btns.length;i++){
        (function (i) {
            btns[i].onclick = function () {
                alert(i);
            }
        })(i)
    }

原理:将每次执行for循环的 i 当作实参传入函数,在外部function函数中的 i 是局部变量,所以每次添加监听的 i 是不同的。由于闭包和作用域链,i 会一直存在,在执行点击的异步任务时可以访问到每个作用域下的 i

2.3 用let替换var

 var btns = document.getElementsByTagName('button');
    for(let i = 0;i<btns.length;i++){
            btns[i].onclick = function () {
                alert(i);
            }
    }

原理:let发挥效果在块级作用域,每个for循环下的代码都在相互独立的块级作用域下,在执行点击监听函数时,内部function的 i 顺着作用域链不会找到全局作用域去,而是在块级作用域找到每个独立的 i

参考:循环遍历加监听的问题

循环遍历小程序中的数字减组件通常是在需要动态生成一组可交互的数字元素,并允许用户进行减操作的情境下。例如,在一个计数器或数学练习场景中,你可以这样做: 1. 首先,创建一个数组或数据结构来存储你想要生成的数字,比如一个包含起始值和步长的对象列表。 ```javascript let numbers = [0, 1, 2, 3, 4]; // 这里仅作为示例,实际可以设置更复杂的动态范围 ``` 2. 使用`for`循环来迭代这个数组,每次循环都会生成一个新的数字减组件实例。 ```javascript for (let i = 0; i < numbers.length; i++) { let numberItem = wx.createSelectorQuery() .select(`<view class="number-item">`) .fields({ properties: true, data: true }) .exec((res) => { if (res && res[0]) { // 根据返回的数据动态设置初始值 res[0].setData({ value: numbers[i] }); // 创建减按钮并添事件监听器 let addButton = wx.createSelectorQuery().select(`<button>+</button>`).node(); addButton.addEventListener('tap', () => { numbers[i]++; res[0].setData({ value: numbers[i] }); }); let subtractButton = wx.createSelectorQuery().select(`<button>-</button>`).node(); subtractButton.addEventListener('tap', () => { numbers[i]--; res[0].setData({ value: numbers[i] }); }); } }); } ``` 在这个例子中,每个`<view class="number-item">`都会有一个显示当前数字的标签和两个按钮,分别用于一和减一。当用户点击按钮时,对应的数字会更新。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值