display=""的悲剧
在学习tab选项卡的时候,要做到点击标题时判断该标题下的菜单是否显示,如果是显示的则将其隐藏,如果是隐藏的则将其显示出来。
1 <!doctype html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Document</title> 6 <style type="text/css"> 7 *{margin:0; 8 padding:0; 9 font-size:13px; 10 list-style:none;} 11 12 .menu{width:210px; 13 margin:50px auto; 14 border:1px solid #ccc;} 15 16 .menu p{height:25px; 17 line-height:25px; 18 font-weight:bold; 19 background:#eee; 20 border-bottom:1px solid #ccc; 21 cursor:pointer; 22 padding-left:5px;} 23 24 .menu div ul{display:none;} 25 26 .menu li{height:24px; 27 line-height:24px; 28 padding-left:5px;} 29 </style> 30 31 </head> 32 <body> 33 <div class="menu" id="menu"> 34 <div> 35 <p>Web前端</p> 36 <ul style="display:block"> 37 <li>JavaScript</li> 38 <li>DIV+CSS</li> 39 <li>jQuery</li> 40 </ul> 41 </div> 42 <div> 43 <p>后台脚本</p> 44 <ul> 45 <li>PHP</li> 46 <li>ASP.net</li> 47 <li>JSP</li> 48 </ul> 49 </div> 50 <div> 51 <p>前端框架</p> 52 <ul> 53 <li>Extjs</li> 54 <li>Esspress</li> 55 <li>YUI</li> 56 </ul> 57 </div> 58 </div> 59 <script type="text/javascript"> 60 function fun(str) { 61 62 return typeof str==='string'?document.getElementById(str):str; 63 } 64 65 var ps=fun("menu").getElementsByTagName("p"); 66 for (var i = ps.length - 1; i >= 0; i--) { 67 ps[i].onclick=function(){ 68 69 if(this.nextSibling.style.display=="none"){ 70 this.nextSibling.style.display="block"; 71 } 72 else{ 73 this.nextSibling.style.display="none"; 74 } 75 } 76 } 77 </script> 78 </body> 79 </html>
注意:1)script放在后面是因为,在html文本加载完后,才取得到id为menu的节点,如果不放在后面,放在window.onload里面也可以。
2)p标签后紧跟ul标签是因为,如果不这样,中间就会产生文本节点,p标签的下一个节点也就不是ul标签了
但是我发现,除了第一个ul在第一次点击ul的时候可以成功,其他两个ul在首次伸缩时需要经过两次,本人初涉javascript,研究了半天chrome如何调试断点后发现
在判断ul的display是否为none的时候,明明“后台脚本”和“前端框架”这两个块都是隐藏的,但是在第一次点击时跳到了else{this.nextSibling.style.display="none"};然后在第二次点击的时候判断才为true,转到了设置display为block的那一步,所以在首次伸缩时需要点击两次。那么为什么隐藏的块第一次判定条件的时候会显示false呢?
结果反反复复调试后发现,第一次点击时,this.nextSibling.style.display="",所以判断为false,那么“”是什么值,明明在css中设定display:none,并且也的确没有显示,为什么会变成“”
因为WEB前端只需点击一次就可成功,我就把目光移到了这两个的区别上,后来我发现,因为WEB前端在ul标签中设定了display=“block”,覆盖了原有的值,所以其他的ul标签会生成一个display=“”的内联式css与“WEB前端”的内联式相对于,而display=“”的意思即为保持原有值不变,则还是display:none。所以为了解决这个问题,有两种方法:
1、修改判断语句为:
1 var dis=this.nextSibling.style.display; 2 3 if(dis=="none"||dis==""){ 4 this.nextSibling.style.display="block"; 5 } 6 else{ 7 this.nextSibling.style.display="none"; 8 }
2:在其他两个ul的标签中也增加内联式css即:
1 <p>后台脚本</p><ul style="display:none"> 2 <li>PHP</li> 3 <li>ASP.net</li> 4 <li>JSP</li> 5 </ul>