一杯茶,一支烟,一个bug玩一天~~要哭了。总算处理掉这个bug了→_→
出现bug的代码:
for(var j = 0; j < rb3h_ul.children.length; j++) {
rb3h_ul.children[j].addEventListener('mouseover', function() {
for(var i = 0; i < rb3h_ul.children.length; i++) {
//干掉所有人
rb3h_ul.children[i].style.borderBottom = '2px solid transparent';
rb3h_ul.children[i].children[0].style.fontWeight = 'normal';
rb3h_ul.children[i].children[0].style.fontSize = '12px';
//干掉所有人
rb3b.children[i].style.display = 'none';
}
//留下我自己
this.style.borderBottom = '2px solid #FF4400';
this.children[0].style.fontWeight = '700';
this.children[0].style.fontSize = '14px';
console.log(j);//输出01234
//留下我自己
rb3b.children[j].style.display = 'block';
});
}
报错提示:
Uncaught TypeError: Cannot read property ‘style’ of undefined 就是在html页面找不到对应元素(的style)
报错原因:
因为 第一个for里面包含的是一个函数 function() 即
addEventListener(‘mouseover’, function() {})
而for里面的j是var声明的局部变量,不能进入function()函数里去循环执行。所以一直在外部进行循环。
当j++后,j变成了5,跳出了for循环,不在for范围内了,成了块区域的变量 j=5就进入function里面执行
但是html页面中,li的元素个数是5,即li的索引号最多是4,j=5进入后就会导致函数在执行时 从html页面找不到索引号是5的li 。所以就会报错上面bug。
解决方法1:
既然for里面的var声明的是局部变量,但是实际是需要块局域变量去到function()函数里面执行的。那就干脆不用var来声明。 换用let声明块局域变量。 即 把for里面的var换成let 就可以了。其他内容都不变。
改后代码演示:
//把var 换成let就解决了
for(let j = 0; j < rb3h_ul.children.length; j++) {
rb3h_ul.children[j].addEventListener('mouseover', function() {
...
解决方法2:
既然是变量j进不去function()函数里去执行循环,那就干脆重新设置一个变量m,然后弄一个变量j的匿名函数,把j和新变量m用匿名函数联系起来, 再把事件发生的函数function()放进匿名函数里。 这样 内外产生了联系, for里面的变量就可以用了。(忘了匿名函数的用法的,到这篇文章的最后内容里带你复习一下)
改后代码演示:
for(var m = 0; m < rb3h_ul.children.length; m++) {
(function(j) {
rb3h_ul.children[j].addEventListener('mouseover', function() {
for(var i = 0; i < rb3h_ul.children.length; i++) {
//干掉所有人
rb3h_ul.children[i].style.borderBottom = '2px solid transparent';
rb3h_ul.children[i].children[0].style.fontWeight = 'normal';
rb3h_ul.children[i].children[0].style.fontSize = '12px';
//干掉所有人
rb3b.children[i].style.display = 'none';
}
//留下我自己
this.style.borderBottom = '2px solid #FF4400';
this.children[0].style.fontWeight = '700';
this.children[0].style.fontSize = '14px';
//console.log(j);
//留下我自己
rb3b.children[j].style.display = 'block';
});
})(m)
}
匿名函数复习:
//匿名函数创建和对应的调用:
//1,没参数
var fun = function() {
}
//调用:
fun();
//2,有参数
var fun = function(j) {
}
//调用
fun(m);
//j是形参,m是实参,调用就是把值m传给j
解决方法2里面的匿名函数就是有参数形式的。fun(m)就是function(j){}(m);
两者是相等的嘛~~但是这里不要忘记要用()把匿名函数包起来,即(function(j){})(m); 这是合法写法。