在css处添加了border样式为了看得更清楚——源代码有一个程序漏洞,存在一个很烦人的大bug。
 <ul class="nav">
<li class="li">
<a href="#">一级菜单</a>
<ul class="subNav">
<li>
<a href="#">二级菜单</a>
</li>
<li>
<a href="#">二级菜单</a>
</li>
<li>
<a href="#">二级菜单</a>
</li>
<li>
<a href="#">二级菜单</a>
</li>
</ul>
</li>
<li class="li">
<a href="#">一级菜单</a>
<ul class="subNav">
<li>
<a href="#">二级菜单</a>
</li>
<li>
<a href="#">二级菜单</a>
</li>
<li>
<a href="#">二级菜单</a>
</li>
<li>
<a href="#">二级菜单</a>
</li>
</ul>
</li>
<li>
<a href="#">一级菜单</a>
</li>
<li>
<a href="#">一级菜单</a>
</li>
<li>
<a href="#">一级菜单</a>
</li>
</ul>

html源码

 <style type="text/css">
* {
margin:;
padding:;
font-size: 14px;
} a {
color: #333;
text-decoration: none
} ul {
list-style: none;
} .nav {
height: 30px;
border-bottom: 5px solid #F60;
margin-left: 50px;
width: 600px;
} .nav li {
float: left;
position: relative;
height: 30px;
width: 120px
} .nav li a {
display: block;
height: 30px;
text-align: center;
line-height: 30px;
width: 120px;
background: #efefef;
margin-left: 1px;
} .subNav {
position: absolute;
top: 30px;
left:;
width: 120px;
/*height:120px;*/
height:;
overflow: hidden;
border: 1px solid #4169E1;/*先找准height的值*/
} .subNav li a {
background: #ddd
} .subNav li a:hover {
background: #efefef
}
</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

JS-鼠标经过显示二级菜单的更多相关文章

  1. 鼠标经过显示二级菜单的js特效

    本文章来给大家推荐一个不错的鼠标经过显示二级菜单js特效效果,有需要了解的朋友可以参考一下 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 T ...

  2. Selenium操作示例——鼠标悬停显示二级菜单,再点击二级菜单或下拉列表

    这两天在玩python中selenium,遇到一个问题,就是鼠标移动到页面中某按钮或菜单,自动弹出二级菜单或下拉菜单,再自动点击其中的二级菜单或下拉列表. 首先,手工操作:打开母校的主页 http:/ ...

  3. Html中鼠标悬停显示二级菜单的两种方法

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  4. 用jQuery做一个三级菜单,鼠标移动到二级菜单的选项上,然后再迅速离开后,当鼠标再移动到该一级菜单或其他二级菜单选项,三级菜单也会显示。

    用jQuery做一个三级菜单,鼠标移动到二级菜单的选项上,然后再迅速离开后,当鼠标再移动到该一级菜单或其他二级菜单选项,三级菜单也会显示. 原因:在为一个元素绑定hover事件之后,用户把光标移入元素 ...

  5. 可以兼容ie6的纯CSS三级鼠标悬停显示/隐藏菜单实现

    本来在chrome上用js写的好好的三级显隐菜单,放到ie6上一测试竟然奇葩般的会瞎闪.问题原因至今没参透,可能是我每次响应事件的处理代码过长??总之我是对ie6幻灭了,去网上搜一搜能支持ie6的下拉 ...

  6. jQuery - 制作点击显示二级菜单效果

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  7. javascript 特效实现(3)—— 鼠标滑过显示二级菜单效果

    1. 关键代码:使用 switch 或 if 判断语句,改变对应的二级菜单显示方式为 block 或 none function selectTabMenu(i){ switch(i){ case 7 ...

  8. 【京东详情页】——原生js爬坑之二级菜单

    一.引言 做京东详情页仿写的时候,要用原生js实现顶部菜单的二级菜单显示与隐藏事件的触发. 过程中遇到了一个坑,在这里与大家分享.要实现的效果如下: 二.坑 谁触发事件?显示.隐藏二级菜单       ...

  9. js点击出现二级菜单,点击二级菜单主菜单换成二级菜单

    点击出现二级菜单 *{ margin:0px auto; padding:0px; } .yiji{ width:200px; height:40px; background-color:red; c ...

随机推荐

  1. HDU5892~HDU5901 2016网络赛沈阳

    A.题意: 有一个n×n的格子, 有50种怪物. 有m个操作, 每次操作会往一个矩形区域放怪物, 每个格子放相同数目的怪物, 或者查询当前50种怪物的奇偶性. 分析:用2^50表示怪物的奇偶,然后就是 ...

  2. [HDOJ5445]Food Problem(优先队列优化多重背包)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5445 题意:多重背包 分析:f[i][j]=max(f[i-1][j-k*w[i]]+k*v[i]) 将j ...

  3. python 英文字串首字母改为大写

    #英文字串首字母改为大写 st = "string" St = st[0].upper() + st[1:] 2016-10-22 后来了解到 python 内部有相关实现,感觉  ...

  4. [jQuery EasyUI系列] 创建增删改查应用

    一.数据收集并妥善管理数据是网络应用共同的必要.CRUD允许我们生产页面列表并编辑数据库记录. 本文主要演示如何使用jQuery EasyUI实现CRUD DataGrid. 将使用到的插件有: da ...

  5. MySQL修改,表结构大幅修改

    ------------------create table t_video_file_temp( video_id bigint not null comment '视频Id', file_md5 ...

  6. java和python细节总结和java中string 的+操作

    //JAVA中对arrayList的初始化,能够分配空间,不能之间让一个ArrayList赋值给另外一个ArrayList,这样是引用赋值,当一个改变时候,另外一个也改变 List<String ...

  7. CDN 备胎技巧

    如果你使用 CDN 服务,建议准备一个备胎,万一 CDN 服务挂了,可以从自己的服务器上读取: <script src="http://cdn.staticfile.org/jquer ...

  8. poj3254 状态压缩dp

    题意:给出一个n行m列的草地,1表示肥沃,0表示贫瘠,现在要把一些牛放在肥沃的草地上,但是要求所有牛不能相邻,问你有多少种放法.     分析:假如我们知道第 i-1 行的所有的可以放的情况,那么对于 ...

  9. Android Studio开发调试使用

    Android Studio调试其实也非常方便,一般问题直接通过AS的DDMS的Logcat就可以搞定.AS支持类似Eclipse的DDMS的所有功能.这里要说的是疑难问题的调试方式,即断点调试. 首 ...

  10. for循环 打印菱形 空 和 实

    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><?ph ...