前几天有个小伙伴做了个选项卡, 让我帮忙看看出了什么问题, 代码如下
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- <style>
- .btn.on{color: #fff;background: red;}
- .content{width: 100px; height: 100px; border: 1px solid #000000; display: none;}
- .content.on{display: block;}
- </style>
- </head>
- <body>
- <input type="button" value="1" class="btn on" />
- <input type="button" value="2" class="btn" />
- <input type="button" value="3" class="btn" />
- <div class="content on">1</div>
- <div class="content">2</div>
- <div class="content">3</div>
- <script>
- var aBtn = document.getElementsByClassName('btn')
- var aCont = document.getElementsByClassName('content')
- for(var i=0;i<aBtn.length;i++){
- aBtn[i].index=i;
- aBtn[i].onclick=function(){
- for(var j=0;j<aBtn.length;j++){
- aBtn[j].className='';
- aCont[j].className='content';
- }
- this.className='on';
- aCont[this.index].className='content on'
- };
- }
- </script>
- </body>
- </html>
大家可以看一下现象, 再看一下代码, 然后上一段我帮她改正的代码.
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- <style>
- .btn.on{color: #fff;background: red;}
- .content{width: 100px; height: 100px; border: 1px solid #000000; display: none;}
- .content.on{display: block;}
- </style>
- </head>
- <body>
- <input type="button" value="1" class="btn on" />
- <input type="button" value="2" class="btn" />
- <input type="button" value="3" class="btn" />
- <div class="content on">1</div>
- <div class="content">2</div>
- <div class="content">3</div>
- <script>
- var aBtn = document.getElementsByClassName('btn')
- var aCont = document.getElementsByClassName('content')
- for(var i=0;i<aBtn.length;i++){
- aBtn[i].index=i;
- aBtn[i].onclick=function(){
- for(var j=0;j<aBtn.length;j++){
- aBtn[j].className='btn';
- aCont[j].className='content';
- }
- this.className='on btn';
- aCont[this.index].className='content on'
- };
- }
- </script>
- </body>
- </html>
我当时一下找到了原因, 是因为她把原本按钮的 class 名字 btn 也给清空了 (当时我以为错误的原因是她是根据 class 名字获取的 btn, 所以清楚 class 名字后就获取不到 btn 了 (这个想法是错误的)).
因为如果获取不到 btn 了怎么可能还会有点击事件呢.... 这时候我又在想了问题出在哪呢, 点击居然同时出现了多个内容框, 就找控制显示的这段: aCont[this.index].className='content on', 想想也不对, 如果我全部隐藏后, 用这段代码就算 index 错乱了, 也只能使其中一个显示啊, 那肯定就是控制显示的那段代码有问题了.
控制显示的代码是放在循环内的, 所以很有可能就是循环出了问题, 既然是循环的话那很有可能就是 i 或者 j 有问题, 而 i 和 j 都是和 btn.length 有关联的, 所以我就有了如下调试代码:
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- <style>
- .btn.on{color: #fff;background: red;}
- .content{width: 100px; height: 100px; border: 1px solid #000000; display: none;}
- .content.on{display: block;}
- </style>
- </head>
- <body>
- <input type="button" value="1" class="btn on" />
- <input type="button" value="2" class="btn" />
- <input type="button" value="3" class="btn" />
- <div class="content on">1</div>
- <div class="content">2</div>
- <div class="content">3</div>
- <script>
- var aBtn = document.getElementsByClassName('btn')
- var aCont = document.getElementsByClassName('content')
- for(var i=0;i<aBtn.length;i++){
- aBtn[i].index=i;
- aBtn[i].onclick=function(){
- alert(aBtn.length)
- for(var j=0;j<aBtn.length;j++){
- aBtn[j].className='';
- aCont[j].className='content';
- }
- this.className='on';
- aCont[this.index].className='content on'
- };
- }
- </script>
- </body>
- </html>
大家可以看到 btn 的 length 变了, 这就很奇怪了, 我既然每个按钮都能点说明三个按钮的点击事件没问题, 然后唯一变化的是每个按钮的 class 名字清空了, 而我每个按钮又是根据 class 名字获取的而且 length 变成了 0, 这是能联想到什么呢? 我的想法是: 通过 docuemnt.getElementsByClassName 获取的 DOM 属性是实时更新的.
不知道大家有没有想到还有一种获取 DOM 的方法, 我们来看看有没有区别
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <title></title>
- <style>
- .btn.on{color: #fff;background: red;}
- .content{width: 100px; height: 100px; border: 1px solid #000000; display: none;}
- .content.on{display: block;}
- </style>
- </head>
- <body>
- <input type="button" value="1" class="btn on" />
- <input type="button" value="2" class="btn" />
- <input type="button" value="3" class="btn" />
- <div class="content on">1</div>
- <div class="content">2</div>
- <div class="content">3</div>
- <script>
- var aBtn = document.querySelectorAll('.btn')
- var aCont = document.getElementsByClassName('content')
- for(var i=0;i<aBtn.length;i++){
- aBtn[i].index=i;
- aBtn[i].onclick=function(){
- alert(aBtn.length)
- for(var j=0;j<aBtn.length;j++){
- aBtn[j].className='';
- aCont[j].className='content';
- }
- this.className='on';
- aCont[this.index].className='content on'
- };
- }
- </script>
- </body>
- </html>
大家可以看到, 虽然清空 class 导致按钮的样式有点问题, 但是选项卡的功能没问题, 并且 length 也一直是 3, 说明 DOM 如果是根据 document.querySelectorAll 来获取, 那么属性不会实时更新, 或者说是被缓存起来的
以上是本人的一些个人想法, 如有错误, 感谢大家指正, 和大家共同进步~~~
来源: http://www.qdfuns.com/article/27295/33585173eac723ee8a1afb754690bb45.html