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>
 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>

<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>

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

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

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏james大数据架构

FrameLayout(框架布局)

框架布局是最简单的布局形式。所有添加到这个布局中的视图都以层叠的方式显示。第一个添加的控件被放在最底层,最后一个添加到框架布局中的视图显示在最顶层,上一层的控件...

20210
来自专栏吴老师移动开发

Flutter ScrollView上拉加载更多关于学习

2018.05.07 更新 上拉加载可以不用Notification,直接用ScrollController,代码如下:

5933
来自专栏前端架构与工程

【翻译】浏览器渲染Rendering那些事:repaint、reflow/relayout、restyle

原文链接:http://www.phpied.com/rendering-repaint-reflowrelayout-restyle/ 有没有被标题中的5个“...

2226
来自专栏xx_Cc的学习总结专栏

六天完成一个简单iOS App - 第六天

3045
来自专栏DeveWork

将你的网站打造成一个iOS Web App

最近在做一个手机主题,据说借用类似 link href="xx.png" rel="nofollow" rel="nofollow" rel="apple-to...

3346
来自专栏更流畅、简洁的软件开发方式

分享一个基于jQuery的锁定表格行列的js脚本。

  网上也有很多锁定行列的方法,一个是使用css,另一个就是专门的控件附带有锁定的功能。css的大多数锁定行,而不能锁定列。好像看过园子里的司徒正美,写过一个用...

2916
来自专栏Material Design组件

后台系统设计(上篇:选择)

在单个选项下,存在多组互斥选项,且互斥选项组之间存在一定关系,可以考虑混用分段控件和常规按钮,由于分段控件在视觉上占用更大的面积,故给人在层级上更加置前。

4522
来自专栏跟着阿笨一起玩NET

TreeComboBox控件范例

本文转载:http://www.cnblogs.com/hoodlum1980/archive/2008/01/30/1058140.html

1132
来自专栏IMWeb前端团队

React同构思想

React比较吸引我的地方在于其客户端-服务端同构特性,服务端-客户端可复用组件,本文来简单介绍下这一架构思想。 出于篇幅原因,本文不会介绍React基础,所...

2089
来自专栏Material Design组件

Human Interface Guidelines —— Text Views & Web Views

923

扫码关注云+社区

领取腾讯云代金券