<button>测试一</button>
<button>测试二</button>
<button>测试三</button>
var btns = document.getElementsByTagName('button')
for(var i = 0; i < btns.length; i++) {
var btn = btns[i]
btn.onclick = function () {
alert(`第${i + 1}个`) // 点击哪个都弹出第四个。原因是:点击按钮执行 onclick 事件绑定函数的时候,for 循环已经结束了,i 是一个全局变量,此时已经变成了 3
}
}
解决方法:
实质就是作用域的问题。
- 使用 let 块作用域:
for(let i = 0; i < btns.length; i++) { var btn = btns[i] btn.onclick = function () { alert(`第${i + 1}个`) } } - 使用闭包:把全局变量 i 以参数的形式传递到了立即执行函数中,在立即执行函数中定义 I 的形参 j,变量 j 就是在立即执行函数作用域中的局部变量了。相当于把每次的 i 都保存在一个局部变量中。
for (var i=0; i< btns.length; i++) { (function(j){ // 此处的形参 j 是局部变量 j var btn = btns[j] btn.onclick = function () { alert(`第${j + 1}个`) } })(i) // 此处的实参 i 是 var 声明的全局变量 i } - 将每个 btn 所对应的 i 保存在 btn 上。
for(let i = 0; i < btns.length; i++) { var btn = btns[i] // 将每个 btn 所对应的 i 保存在 btn 上 btn.index = i btn.onclick = function () { alert(`第${this.index + 1}个`) } }
JS事件绑定坑
本文探讨JavaScript中事件绑定的常见问题,特别是使用var关键字时的作用域陷阱,导致所有按钮点击事件触发相同行为。文章提供了解决方案,包括使用let声明变量、闭包技巧以及将变量保存在元素上的方法。






