具体出现的错误问题是这样的
test2.html:29 Uncaught TypeError: Cannot read property ‘style’ of undefined at HTMLTableCellElement.nav..oclick (test2.html:29)
在这里我的代码是这样的,用来实现将点击的字变红
然后就出现了上面出现的错误
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<style>
.pink_bgc{
background-color:pink;
width: 400px;
height:30px;
text-align: center;
cursor: pointer;
}
</style>
<body>
<table class="pink_bgc" cellspacing="0">
<tr>
<td class="red_bgc">我是0</td>
<td>我是1</td>
<td>我是2</td>
<td>我是3</td>
</tr>
</table>
<script type="text/javascript">
var nav = document.querySelector('table').querySelectorAll('td');
for(var i=0;i<nav.length;i++){
nav[i].onclick=function(){
nav[i].style.color='red';
}
}
</script>
</body>
下面我们简单的分析一下
(以下代码均只展示JavaScript部分代码,因为HTML和CSS部分这里不做修改了)
第一次尝试
首先先简单的在for循环后面添加一个 console.log(i),来观察 i 在进入onclick之前是怎么变化的
代码如下:
<script type="text/javascript">
var nav = document.querySelector('table').querySelectorAll('td');
for(var i=0;i<nav.length;i++){
console.log(i);
nav[i].onclick=function(){
nav[i].style.color='red';
}
}
</script>
</body
输出结果:
0 1 2 3
和你想象到的一样吗,其实我猜想到的应该是一样的,
但是再一想,那意思是onclick的function功能后console.log(i)输出的是4?
第二次尝试
确实是这样的
代码如下:
<script type="text/javascript">
var nav = document.querySelector('table').querySelectorAll('td');
for(var i=0;i<nav.length;i++){
console.log(i);
nav[i].onclick=function(){
console.log(i);
nav[i].style.color='red';
}
}
</script>
输出结果
那么自然而然地就能说明了问题了
那么为什么呢,你的理解是不是加入我点击的是我是1那么输出的就应该是 1
我的猜测是这样的,i 只是用来不断循环,用来判断你有没有进行onclick点击操作,但是至于点击的哪一个,i 它自己也不是很清楚,
所以在onclick事件中不用nav[i],而是使用this,
虽然许多人解释this就是nav[i],但是经过这样的测试,就可以很明显的说明this在onclick中指的一定不是nav[i]
那么如何解决呢
解决错误的方法——自定义属性
上述代码进行修改
代码如下
<script type="text/javascript">
var nav = document.querySelector('table').querySelectorAll('td');
for(var i=0;i<nav.length;i++){
nav[i].setAttribute('index',i);
nav[i].onclick=function(){
var test = this.getAttribute('index');
console.log(test);
nav[test].style.color='red';
}
}
</script>
输出结果
(这里我们依次点击2130)
所有字依次变为红色
那么这又是为什么呢
解释说明
自定义属性,就是自己定义属性给html标签
nav[i].setAttribute(‘index’,i);
如上代码,就是将i的值依次赋给td标签
也就是第一个td标签出现了一个类似class的属性,只不过这个属性的名字是index,他的内容就是0
而第二个也出现了一个类似class属性的index属性,他的内容是1
依次进行
那么也就是在html标签里有了每个td的序列号,那么我们通过this.getAtrribute(‘index’)操作,就可以将所点击的td的序列号赋给一个变量(上面代码中是test)
getAttribute和setAttribute均是自定义属性的操作
这下该懂了吧