好像是第二次遇到这个问题,必须要总结一下!!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<style type="text/css">
li{
width: 100px;
height: 50px;
background-color: red;
margin-bottom: 10px;
}
</style>
<body>
<ul id="ulList">
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<script>
var lis = document.getElementById("ulList").getElementsByTagName("li");
for(var i=0;i<lis.length;i++){
lis[i].onclick = function(){
console.log(i);
} }
</script>
</body>
</html>
如果按照以上方法,无论点击哪一个li标签,i的值都会是4,并不能像我们所想的那样打印出0,1,2,3,原因是什么呢?
暂时也不太清楚,好像涉及闭包,因为也没学到,就参考别人回答总结一下。
for循环是一个外部闭包,依次绑定的点击事件是一个函数实例,也产生了一个闭包域,它引用了外部闭包的变量i,外部闭包域中i的最终值为4,点击事件触发时引用外部闭包变量i(此时i=4),所以输出的值全为4。
暂时先写两种自己能掌握的解决方法:
方法一:在for循环中点击事件外套一个自执行的匿名函数,将索引变量i保存到匿名函数的形参中
<script>
var lis = document.getElementById("ulList").getElementsByTagName("li");
for(var i=0;i<lis.length;i++){
(function(arg){
lis[i].onclick = function(){
console.log(arg);
}
})(i);
}
</script>
方法二:在for循环中,为每一个要点击的对象创建属性用来保存索引变量i
<script>
var lis = document.getElementById("ulList").getElementsByTagName("li");
for(var i=0;i<lis.length;i++){
lis[i].i = i; //创建属性保存变量i
lis[i].onclick = function(){
console.log(this.i);
// console.log(lis[i].i);绝对不能这样写,要不然 Uncaught TypeError: Cannot read property 'i' of undefined
}
}
</script>