问题
在很多时候需要为所有 li 添加一个相同的单击事件。如下:每次点击 li 都只能在最后一个有效,即不能输出对应的 i 值。这是因为es5中只有全局作用域和局部作用域,使用 var 会执行完 for 循环再执行里面的事件,所以只能一直弹出 i 的值为 5。
<body>
<div class="box">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</div>
</body>
<script type="text/javascript">
var box = document.querySelector('.box');
var lis = box.querySelectorAll('li');
for(var i = 0; i < lis.length; i++) {
lis[i].onclick = function() {
alert(i);
}
}
</script>
解决办法
1、使用闭包函数
能够解决这个问题
<body>
<div class="box">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</div>
</body>
<script type="text/javascript">
var box = document.querySelector('.box');
var lis = box.querySelectorAll('li');
for(var i = 0; i < lis.length; i++) {
(function(args) {
lis[args].onclick = function() {
alert(args + 1);
};
})(i)
}
</script>
2、使用es6新增let
es6中重新定义了作用域,新增了块级作用域,将 for 循环中的 var 改为 let 能够有效的解决这个问题
<body>
<div class="box">
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
</div>
</body>
<script type="text/javascript">
var box = document.querySelector('.box');
var lis = box.querySelectorAll('li');
for(let i = 0; i < lis.length; i++) {
lis[i].onclick = function() {
alert(i);
}
}
</script>