var btns = document.querySelectorAll('.btn'); // 6 elements
var output = document.querySelector('#output');
var events = [1, 2, 3, 4, 5, 6];
// Case 1
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = function(evt) {
output.innerText += 'Clicked ' + events[i];
};
}
// Case 2
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = (function(index) {
return function(evt) {
output.innerText += 'Clicked ' + events[index];
};
})(i);
}
// Case 3
for (var i = 0; i < btns.length; i++) {
btns[i].onclick = (function(event) {
return function(evt) {
output.innerText += 'Clicked ' + event;
};
})(events[i]);
}
为何case1那里的绑定方法是错误的?
请了解js闭包
js闭包相关,找下相关的文章或者书籍看看
因为当你click的时候i
已经是 btns.length
了,这跟js的闭包有关系,建议你了解一下。
解决办法有很多种,常见的有如下三种办法(建议你了解完闭包之后再回来看):
//1. 最简单的方法 将变量 i 保存给在每个btns对象上
for (var i = 0; i < btns.length; i++) {
btns[i].index = i;
btns[i].onclick = function(evt){
output.innerText += 'Clicked ' + events[this.index];
}
}
//2. 将变量 i 保存在匿名函数自身
for (var i = 0; i < btns.length; i++) {
(btns[i].onclick = function(evt){
output.innerText += 'Clicked ' + events[arguments.callee.i];
}).i = i;
}
//3. 加一层闭包,i 以局部变量形式传递给内层函数
for (var i = 0; i < btns.length; i++) {
(function(){
var temp = i;
btns[i].onclick = function(evt){
output.innerText += 'Clicked ' + events[temp];
}
})();
}