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); 这是合法写法。

  • 24
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值