问题描述:
var lis =document.querySelectorAll("li");
for (var i = 0; i < lis.length; i++) {
lis[i].onclick = function() {
console.log(i); //不论点击哪一个li标签,i的值都会是lis.length
}
出现原因:
for循环是一个外部闭包,依次绑定的点击事件是一个函数实例,也产生了一个闭包域,
它引用了外部闭包的变量i,外部闭包域中i的最终值为4,点击事件触发时引用外部闭包变量i,外部闭包域中i的最终值
若i=10则输出的值:console.log(i)//10 10...10
解决方法:
1.设置自定义属性:在for循环中,为每一个要点击的对象创建属性用来保存索引变量
1.1.设置css的自定义属性
1.2. 设置js的自定义属性
2.使用闭包:在for循环中点击事件外, 套一个自执行的匿名函数,将索引变量i保存到匿名函数的形参中
3.把循环体中的var替换成let:for (let i = 0; i < lis.length; i++) {}
代码:
1.设置自定义属性:在for循环中,为每一个要点击的对象创建属性用来保存索引变量
var lis = document.querySelectorAll("li");
for (var i = 0; i < lis.length; i++) {
//设置自定义属性lis_index
lis[i].setAttribute("lis_index", i);
// console.log(lis[i].getAttribute("lis_index")); //成功获得0 1 2...10
lis[i].onclick = function() {
//自定义属性ali_index的获取
var index = this.getAttribute("lis_index");
console.log(index, lis[index].innerHTML); //点击哪个li,就输出其索引和其文本内容
}
}
2.使用闭包:在for循环中点击事件外,套一个自执行的匿名函数,将索引变量i保存到匿名函数的形参index中
var lis = document.querySelectorAll("li");
for (let i = 0; i < lis.length; i++) {
(function() {
var index = i;
lis[index].addEventListener("click", function() {
console.log(index);
});
})();
}
完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>获取循环中的点击事件的每个li标签</title>
<style>
/* 定义css自定义属性 */
:root {
--my-green: #52ec80;
}
li {
list-style-type: none;
width: 300px;
height: 100px;
background: skyblue;
border-radius: 10%;
/* 使用自定义颜色,green是自定义颜色不生效时的默认替代方案 */
box-shadow: 5px 5px 5px var(--my-green, green);
margin: 5px;
font-size: 30px;
color: white;
text-align: center;
line-height: 100px;
}
li:active {
background: blue;
}
</style>
</head>
<body>
<ul>
<li>按钮1</li>
<li>按钮2</li>
<li>按钮3</li>
</ul>
</body>
<script>
// 出现问题:点击哪个li都输出最后一个
// for (var i = 0; i < lis.length; i++) {
// lis[i].onclick = function() {
// console.log(i);
// }
// }
/*****解决方法一:使用闭包*****/
// 解决方法一:使用闭包(给点击事件套一个自执行函数)
// for (var i = 0; i < lis.length; i++) {
// (function(index) {
// lis[index].onclick = function() {
// console.log(index);
// }
// })(i);
// }
//示例二: 延时器获取i(实际上此处的延时器相当于一个自动的点击事件)
// for (var i = 0; i < lis.length; i++) {
// setTimeout(() => {
// console.log(i); //只能获取3
// }, 1000);
// }
// 解决方法一:使用闭包
// for (var i = 0; i < lis.length; i++) {
// (function(index) {
// setTimeout(() => {
// console.log(index);
// }, 1000);
// })(i);
// }
/*****解决方法二:使用自定义属性*****/
// for (var i = 0; i < lis.length; i++) {
// // 给每个li设置自定义属性li_index,属性值是i
// lis[i].setAttribute("li_index", i);
// lis[i].onclick = function() {
// var idx = this.getAttribute("li_index");
// console.log(idx);
// };
// }
/*****解决方法三: 把var改成let*****/
for (let i = 0; i < lis.length; i++) {
lis[i].onclick = function() {
console.log(i);
}
}
</script>
</html>