想写个循环测试一下onmouseout,onmouseover,下面是具体代码。
下面这段代码不能正常执行
var yy = document.getElementsByClassName("div_inTop_001");
for (var i = 0; i < yy.length; i++) {
yy[i].addEventListener("mouseover", myfunction0000);
yy[i].addEventListener("mouseout", myfunction0001);
function myfunction0000(){
yy[i].style.backgroundColor="#A52A2A";
console.log(i);
}
function myfunction0001(){
yy[i].style.backgroundColor="#5B5B5B";
console.log(i);
}
}
错误提示:开发工具(idea)提示:mutable variable is accessible from closure
浏览器报错提示:
可以正确执行的代码:
var yy = document.getElementsByClassName("div_inTop_001");
for (var i = 0; i < yy.length; i++) {
yy[i].addEventListener("mouseover", myfunction0000);
yy[i].addEventListener("mouseout", myfunction0001);
function myfunction0000(){
this.style.backgroundColor="#A52A2A";
console.log(i);
}
function myfunction0001(){
this.style.backgroundColor="#5B5B5B";
console.log(i);
}
}
我想知道为什么上面的那一段代码不能运行?下面那段代码为什么能运行
yy.length=5
因为你需要在事件内使用事件外的循环变量i。
你的循环中只是为元素绑定事件,这时事件并没有触发执行。
等到事件触发时,那个循环早已经结束了,那时的i的值已经是循环最大值加1了。
所以需要用一些方式保存住当前循环的i的值。
方案1为:用闭包保存住当前循环的i的值。
for(var i=0;i<doms.length;i++) {
(function(i){
doms[i].onclick=function(){
alert(i);
}
})(i);
}
方案2为:用let块作用域变量,原理也是闭包(ie11以前不支持)
for(var i=0;i<doms.length;i++) {
let j = i;
doms[i].onclick=function(){
alert(j);
}
}
方案3为:在事件函数内不使用循环变量i,而是用this获取触发事件的元素
for(var i=0;i<doms.length;i++) {
doms[i].index = i;
doms[i].onclick=function(){
alert(this.index);
}
}
如果你只是要获取触发事件的元素,而不需要使用循环变量i。可以直接在事件函数内用this就可以了。