案例需求
鼠标点击三个盒子,盒子变色。
结构和样式代码
<div class="container">
<h2 class="page-header">点击切换颜色</h2>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
.page-header {
font-weight: normal;
border-bottom: 1px solid #333;
}
.item {
float: left;
width: 100px;
height: 70px;
border: 1px solid #3b9b9b;
margin-left: 10px;
}
使用var
let items = document.getElementsByClassName("item");
for (var i = 0 ; i < items.length ; i++){
items[i].onclick = function(){
items[i].style.background = "pink";
}
}
console.log(window.i); //3
点击后结果
原因这里var声明的变量 i 是全局变量,当事件绑定完退出for循环时,i 的值为3,当鼠标点击触发事件时,找不到items[3]这一个对象所以报错。
使用let
let items = document.getElementsByClassName("item");
for (var i = 0 ; i < items.length ; i++){
items[i].onclick = function(){
items[i].style.background = "pink";
}
}
console.log(window.i); //undefine
点击后顺利变色
原因:let时ES6新增的,具有在当前块级作用域中有效。
所以上述代码可以像下面这样理解,当点击事件发生时,事件函数在自己的作用域里找不到i,于是向上一级找,找到了i
当然,let不会影响作用域链
{
let i = 0;
items[i].onclick = function(){
items[i].style.background = "pink";
}
}
{
let i = 1;
items[i].onclick = function(){
items[i].style.background = "pink";
}
}
{
let i = 2;
items[i].onclick = function(){
items[i].style.background = "pink";
}
}
总结
以后循环绑定事件时可以尽量使用let关键字避免出错,当然,上面的案例直接都用this就没有这个问题啦。
<br>
如有错误,欢迎指正!