Uncaught TypeError: Cannot read property 'style' of undefined这个bug的两种解决方法

一杯茶,一支烟,一个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); 这是合法写法。

原创文章 28 获赞 35 访问量 1万+

猜你喜欢

转载自blog.csdn.net/tuzi007a/article/details/105906812