动态绑定按钮点击事件时索引传递异常问题求助
问题解决:按钮点击事件无法正确传递循环索引
问题重现
HTML代码:
<button id="0">btn1</button> <button id="1">btn2</button> <button id="2">btn3</button>
JavaScript代码:
var items = ["cars", "trucks", "tankers"] for (var i = 0; i < items.length; i++) { document.getElementById(i).onclick = function(){handle(i)}; } function handle(index){ console.log(items[index]); }
点击任意按钮后控制台输出undefined,而非预期的对应数组元素。
问题原因
用var声明的循环变量i是函数级作用域,整个循环里只有一个i的引用。当循环结束时,i的值已经变成了3(循环条件为i < items.length,最后一次循环后i自增到3)。等到按钮被点击时,事件处理函数才会读取i的值,此时i=3,而items[3]不存在,所以输出undefined。
几种修复方案
方案1:用let声明循环变量(ES6+)
let是块级作用域,每次循环都会创建一个新的i变量,绑定到当前迭代的事件处理函数中:
for (let i = 0; i < items.length; i++) { document.getElementById(i).onclick = function(){handle(i)}; }
方案2:用立即执行函数(IIFE)创建闭包
通过闭包把每次循环的i值保存下来,避免后续被覆盖:
for (var i = 0; i < items.length; i++) { (function(currentIndex) { document.getElementById(currentIndex).onclick = function(){handle(currentIndex)}; })(i); }
方案3:利用按钮的id获取索引
直接从点击的按钮元素上读取id并转为数字,不依赖循环变量:
for (var i = 0; i < items.length; i++) { document.getElementById(i).onclick = function(){ handle(parseInt(this.id)); }; }
方案4:用forEach遍历数组
forEach的回调函数会自动保留当前的索引值,写法更简洁:
items.forEach(function(_, index) { document.getElementById(index).onclick = function(){handle(index)}; });
内容的提问来源于stack exchange,提问作者Belko DIALLO
相关产品推荐
相关产品推荐

