zoukankan      html  css  js  c++  java
  • JS-鼠标经过显示二级菜单

    在css处添加了border样式为了看得更清楚——源代码有一个程序漏洞,存在一个很烦人的大bug。
     1 <ul class="nav">
     2         <li class="li">
     3             <a href="#">一级菜单</a>
     4             <ul class="subNav">
     5                 <li>
     6                     <a href="#">二级菜单</a>
     7                 </li>
     8                 <li>
     9                     <a href="#">二级菜单</a>
    10                 </li>
    11                 <li>
    12                     <a href="#">二级菜单</a>
    13                 </li>
    14                 <li>
    15                     <a href="#">二级菜单</a>
    16                 </li>
    17             </ul>
    18         </li>
    19         <li class="li">
    20             <a href="#">一级菜单</a>
    21             <ul class="subNav">
    22                 <li>
    23                     <a href="#">二级菜单</a>
    24                 </li>
    25                 <li>
    26                     <a href="#">二级菜单</a>
    27                 </li>
    28                 <li>
    29                     <a href="#">二级菜单</a>
    30                 </li>
    31                 <li>
    32                     <a href="#">二级菜单</a>
    33                 </li>
    34             </ul>
    35         </li>
    36         <li>
    37             <a href="#">一级菜单</a>
    38         </li>
    39         <li>
    40             <a href="#">一级菜单</a>
    41         </li>
    42         <li>
    43             <a href="#">一级菜单</a>
    44         </li>
    45     </ul>
    html源码
     1 <style type="text/css">
     2 * {
     3 margin: 0;
     4 padding: 0;
     5 font-size: 14px;
     6 }
     7 
     8 a {
     9 color: #333;
    10 text-decoration: none
    11 }
    12 
    13 ul {
    14 list-style: none;
    15 }
    16 
    17 .nav {
    18 height: 30px;
    19 border-bottom: 5px solid #F60;
    20 margin-left: 50px;
    21 width: 600px;
    22 }
    23 
    24 .nav li {
    25 float: left;
    26 position: relative;
    27 height: 30px;
    28 width: 120px
    29 }
    30 
    31 .nav li a {
    32 display: block;
    33 height: 30px;
    34 text-align: center;
    35 line-height: 30px;
    36 width: 120px;
    37 background: #efefef;
    38 margin-left: 1px;
    39 }
    40 
    41 .subNav {
    42 position: absolute;
    43 top: 30px;
    44 left: 0;
    45 width: 120px;
    46 /*height:120px;*/
    47 height: 0;
    48 overflow: hidden;
    49 border: 1px solid #4169E1;/*先找准height的值*/
    50 }
    51 
    52 .subNav li a {
    53 background: #ddd
    54 }
    55 
    56 .subNav li a:hover {
    57 background: #efefef
    58 }
    59 </style>
    style样式

    <script>
    window.onload = function() {
    var aLi = document.getElementsByTagName('li');
    for(var i = 0; i < aLi.length; i++) {
    aLi[i].onmouseover = function() {
    //鼠标经过一级菜单,二级菜单动画下拉显示出来
    var sub = this.getElementsByTagName('ul')[0];
    if(sub) {
    var This = sub;
    clearInterval(This.timer);
    This.timer = setInterval(function() {

    //alert('+20');//弹出+20,以判断在这里执行了,几次+20.经判断,他是执行了6次,即加到了120,在120的时候,因为if判断,执行了clear
    This.style.height = This.offsetHeight + 20 + "px";
    if(This.offsetHeight >= 120) {

    sub.style.height = 120+'px';//解决2
    clearInterval(This.timer)

    //alert('跳出来了');//clear执行后,跳出本次循环

    }
    }, 30)

    //alert(sub);//本来以为放在这里弹窗。会在加完120后再执行,没想到他先执行的这个,并且弹出ullistElement,即说明他找到了subNav的ul,
      问题来了,当加载完成后,请你尝试把鼠标再放到二级菜单上移动一下,你没选择一个二级菜单,他就是把这三个alert再执行一遍,然后你就会看到ul的长度又加了20,当你不停的上下晃动鼠标,二级菜单就会不停的添加。最后加的老长。为了明显,我加了border,效果一目了然。
      原因:这里,通过这个代码:alert(aLi.length);原因就明显了,因为开头的aLi,获得的是body中所有的li,包括二级菜单的。就是说你在二级菜单的每一个li上晃一下,他都会认为你是在重新执行了aLi.onmouseover这个代码,流程就再走了一遍。但是因为在高度加20那里,他高度先增加了20,然后一判断,发现高度大于120了,就赶紧跳出了。所以就会每次你晃一下,只增加了20。
      解决1,从源头,只找对应的li,试过以后,我还没发现真谛。难道是要给ul一个id,然后通过id获得ul下的li集合,再判断谁有二级菜单进行显示
      解决2:高度处,在判断那里,如果高度大于120了,我们就直接让高度等于120,不就得了,以后他再长,也会被这一条限制住。sub.style.height = 120+'px';
      解决3:判断处,再增加前我先判断是不是大于120行不行,是的话你就停止,不是就继续。问题也就可以解决了。代码:

    if(This.offsetHeight >= 120){
    clearInterval(This.timer);
    }else{
    This.style.height = This.offsetHeight + 20 + "px";
    }

      最后mouseout那里,就不用管了,毕竟ul的长度不会出格了,就不需要加强防备了


    }
    }
    </script>

        <script>
    window.onload = function() {
                var aLi = document.getElementsByClassName('li');
                for(var i = 0; i < aLi.length; i++) {
                    aLi[i].onmouseover = function() {
                            var sub = this.getElementsByClassName('subNav')[0];
                            if(sub) {
                                clearInterval(sub.timer);
                                sub.timer = setInterval(function() {
                                    sub.style.height = sub.offsetHeight + 20 + "px";
                                    if(sub.offsetHeight > 120) {
                                        sub.style.height = 120+'px';
                                        clearInterval(sub.timer)
                                    }
                                }, 30)
                            }
                        }        
                    aLi[i].onmouseout = function() {
                        var sub = this.getElementsByTagName('ul')[0];
                        if(sub) {
                            clearInterval(sub.timer);
                            sub.timer = setInterval(function() {
                                sub.style.height = sub.offsetHeight - 20 + "px";
                                if(sub.offsetHeight <= 0) {
                                    clearInterval(sub.timer)
                                }
                            }, 30)
                        }
                    }
                }
            }
        </script>
    调整好的js源码

      后来我也发现了收缩不干净,总是多出外面几像素,但是我把border删掉他就收缩干净了,我不知道在js处是不是还存在问题导致的收缩不干净。

      幕友是这么回答的:收缩不干净是因为宽高不会小于零,比如你在某一刻高度为3,但是要减去4,这个时候高度的值不会等于-1,也不会等于0,而是选择不执行。也就是说,高度会一直为3,所以if里面的将高度设置为零的语句根本就没有执行,同时定时器也没有清除。然后没收缩干净的就是很小的高度为3的部分。关键是定时器还一直在占用系统的资源。希望对认真做练习和思考的小伙伴们有帮助。

    来自慕课练习题的问题:http://www.imooc.com/code/1737

  • 相关阅读:
    day9习题
    生产者消费者模型(吃包子例子)
    map 函数----filter函数
    #返回值包含函数
    #把函数当作参数传给另一个函数
    异常和错误!
    递归调用
    局部和全局案例!!
    全局变量与局部变量2
    全局变量与局部变量
  • 原文地址:https://www.cnblogs.com/padding1015/p/5884024.html
Copyright © 2011-2022 走看看