为了账号安全,请及时绑定邮箱和手机立即绑定

这段js是不是有问题?有漏洞哎

给subNav的样式中添加一个border,你会很清楚的发现这段代码的问题。好像清除不了定时器。鼠标在展开的二级菜单上来回的上下晃,二级菜单的高度就会不听得增加。不知道有没有人发现这个问题?具体怎么解决?

http://img1.sycdn.imooc.com//57df47f000016aed02730558.jpg

正在回答

4 回答

课程水平伸缩菜单制作中是这么设置的,这个练习题中CSS里面的设置和水平伸缩菜单模块的CSS样式设定不一样的,不能直接套用课程的代码,我这边运行是显示不出来二级菜单的,<ul class="subNav">大小仍为120*0,高度值为0;题目CSS中设置了.subNav{ position:absolute; top:30px; left:0; width:120px; height:0; overflow:hidden},高度为0,overflow:hidden,我也是新手一枚,说的不对还请见谅,实现要求的效果可以这样写,请参考:

<script>

window.onload=function(){

    var aLi=document.getElementsByTagName('li');

for(var i=0; i<aLi.length; i++){

aLi[i].onmouseover=function(){

            //鼠标经过一级菜单,二级菜单动画下拉显示出来

this.getElementsByTagName("ul")[0].style.overflow="visible";

}     /*此处可以用上你的判断语句,var This=this.getElementsByTagName("ul")[0];

    if(This)  This.style.overflow="visible";   个人觉得此步骤可以不用,aLi[2]、aLi[3]、aLi[4] 没有ul子节点,for循环正常循环就可以 */


 //鼠标离开菜单,二级菜单动画收缩起来。

aLi[i].onmouseout=function(){

                this.getElementsByTagName("ul")[0].style.overflow="hidden"; 

}

}

}

</script>


0 回复 有任何疑惑可以回复我~
#1

xing_org1 提问者

你这样写验证过了吗?可以用么?
2016-09-19 回复 有任何疑惑可以回复我~
#2

xing_org1 提问者

我的主要意思就是,解决 var aLi=document.getElementsByTagName('li');这个获取下来13个li(包括二级菜单中的li)而导致的问题。和长度没有关系,是这个方法获取了二级菜单的li,导致鼠标放到二级菜单的li上面时,还会再调用一次onmouseover这个函数。进而导致二级菜单ul.subNav的高度不断加高的问题
2016-09-19 回复 有任何疑惑可以回复我~
#3

慕粉1462636306 回复 xing_org1 提问者

我这个你试下运行时没问题的,你的那个我没运行出来,<ul class="subNav">大小仍为120*0,我觉得还是和CSS布局有关,此处有绝对定位和overflow:hidden的问题,如果是说一级菜单上下滑动套教程里面水平圆角菜单的代码应该是没错的,练习题中二级菜单一开始就是height=0,overflow:hidden,所以想着将overflow:visible不就可以啦,菜鸟一枚与楼主共勉,感觉你也是很善于思考问题的,向你学习把这些概念弄明白吃透
2016-09-19 回复 有任何疑惑可以回复我~
#4

xing_org1 提问者 回复 慕粉1462636306

不是不是,我们目前说的不是一个问题,我说的是慕课网给的js参考代码有问题,我在找修补这段代码的解决方法,而你说的可能是另一种实现效果的做法吧。另外,如果height是0;你overflow是可见的也没用,鼠标点击或经过还是不能显示二级菜单,因为高度是0
2016-09-19 回复 有任何疑惑可以回复我~
#5

xing_org1 提问者

非常感谢!
2016-09-19 回复 有任何疑惑可以回复我~
#6

xing_org1 提问者 回复 慕粉1462636306

0;去掉吧,不然块元素高度是0还是不能显示吧。 另外,那个每次高度增加20的js代码,是可以做到那种缓动画的效果,直接设置overflow的话,动画比较生硬。拙见。
2016-09-19 回复 有任何疑惑可以回复我~
查看3条回复

昨天重新认真的把代码写了一遍,试了你说的这种方法,如果if(sub.offsetHeight > 120) clearInterval(sub.timer),确实会出现你说的这些个问题,在二级菜单上面晃来晃去的,onmouseover不断触发,高度会不断增加,onmuouseover事件有冒泡行为,子节点li鼠标移动事件引发父节点ul行为,增加sub.style.height ="120px"限定高度消除子节点引起动画事件,当然动画效果会生硬,或者也可以用onmouseenter和onmouseleave,网上还有其他方法解决onmouseover冒泡行为,后面Jquery也会讲解一些;此外针对用overflow属性做法,个人理解是这样的,CSS父模块ul height=0,overflow=hidden,设置overflow=visible,虽然height=0,但是里面内容li高度不为0,利用overflow溢出显示出二级菜单,不知道这种是不是很取巧;此外也可以设置边框观察下鼠标移走时的现象,试下sub.style.height = sub.offsetHeight +/- 120+ "px"的效果,试着将border加粗加细的效果,拙见哈哈

0 回复 有任何疑惑可以回复我~
#1

xing_org1 提问者

嗯嗯,受教了,谢谢你的细心回答
2016-09-20 回复 有任何疑惑可以回复我~

研究好了,解决方法如下:

首先是对源代码的研究:

window.onload = function() {

var aLi = document.getElementsByClassName('li');

// alert(aLi.length);

for(var i = 0; i < aLi.length; i++) {

aLi[i].onmouseover = function() {

//鼠标经过一级菜单,二级菜单动画下拉显示出来

var sub = this.getElementsByClassName('subNav')[0];

if(sub) {//如果这个li当前是有sub的,即sub==true,执行如下代码:

// var This = sub;这里其实可以删除不用this的。

clearInterval(sub.timer);

sub.timer = setInterval(function() {

//我插入了三个alert进行调试:

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

sub.style.height = sub.offsetHeight + 20 + "px";

if(sub.offsetHeight > 120) {

sub.style.height = 120+'px';

clearInterval(sub.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的长度不会出格了,就不需要加强防备了、

}

}


0 回复 有任何疑惑可以回复我~
#1

慕粉1462636306

此外小错误,sub.style.height = 120+'px';这样写sub.style.height = "120px";
2016-09-19 回复 有任何疑惑可以回复我~
#2

xing_org1 提问者 回复 慕粉1462636306

嗯嗯,没错。不过我那么些也是可以运行的,但是少一个加号也是个好主意。
2016-09-19 回复 有任何疑惑可以回复我~

建议代码贴出来,说清楚问题,这样大家好分析

0 回复 有任何疑惑可以回复我~
#1

xing_org1 提问者

谢谢,我已经找到问题的原因了,你可以看看我的代码就知道我在说什么了
2016-09-19 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消
导航条菜单的制作
  • 参与学习       123899    人
  • 解答问题       813    个

水平、垂直、圆角导航条菜单,让您的技术探索之路更高效

进入课程

这段js是不是有问题?有漏洞哎

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信