JavaScript菜单循序渐进
说起菜单不同的人可能有不同感受,有的人感觉这个很有趣,做菜单是一件很好玩的事;也有的人会对它不屑一顾,认为这些都是雕虫小技;还有一部分人会认为,这个完全没必要仔细看,一切都可以拿来主义,网上一搜一大把,焉用亲自去写?
本文并不是什么很高深的见解或者观点独到,只是想从一些示例来寻找菜单制作的思路,掌握了思想就可以融会变通,想要什么样的菜单,只要想出来,就可以尝试去实现你的创意。
有人一看,说你用JavaScript做菜单,这个太不友好了,现在纯CSS的菜单到处都是。的确如此,我blog里也有很多纯CSS菜单的demo,但纯CSS做出来的菜单毕竟效果很有限,有些创意但靠CSS可能无法实现,用JavaScript写菜单也是一种尝试,可以实现很炫的效果(网上JavaScript模仿flash的效果很多)。
但由于JavaScript里事件具有冒泡的特性,在处理菜单的时候,往往被冒泡搞的很头疼,特别是给菜单加上动画特效之后,更是让很多人郁闷,有人可能会用timer或者坐标判断来解决这个问题,但其实都不理想,网上还有老外写的一个jQuery插件,专门用于解决这个问题,可以说JavaScript做菜单并不是一件小事。
好了,闲话少说,开始第一步,做一个简单的下拉菜单:
用到的HTML代码:
程序代码<ul id="nav">
<li>
<a href="#">江苏省</a>
<div class="child_menu">
<a href="#">南京</a>
<a href="#">苏州</a>
<a href="#">无锡</a>
<a href="#">常州</a>
<a href="#">镇江</a>
<a href="#">徐州</a>
</div>
</li>
<li>
<a href="#">浙江省</a>
<div class="child_menu">
<a href="#">杭州</a>
<a href="#">宁波</a>
</div>
</li>
<li>
<a href="#">福建省</a>
<div class="child_menu">
<a href="#">厦门</a>
<a href="#">福州</a>
<a href="#">泉州</a>
</div>
</li>
<li>
<a href="#">广东省</a>
<div class="child_menu">
<a href="#">广州</a>
<a href="#">深圳</a>
<a href="#">东莞</a>
<a href="#">潮州</a>
</div>
</li>
<li>
<a href="#">山东省</a>
<div class="child_menu">
<a href="#">青岛</a>
<a href="#">威海</a>
<a href="#">泰安</a>
<a href="#">济南</a>
<a href="#">德州</a>
</div>
</li>
</ul>
CSS样式代码:
程序代码#nav{ width:500px; margin:0px auto; list-style:none; font-size:12px; text-align:center; line-height:26px;}
#nav li{ width:100px; float:left;}
#nav li a{ display:block; width:99px; border-bottom:#FFFFFF 1px solid; text-decoration:none; background:#333333; height:26px; color:#CCCCCC;}
#nav li a:hover{ background:#CCCCCC; color:#333333;}
#nav li div{ display:none;}
后面的JavaScript代码都是引用上面的HTML和样式,示例使用了JQuery,如果要查看效果,运行后需要刷新一下页面。
基本菜单效果的实现:
程序代码var nav_main=$("#nav>li>a");
var nav_child=$("#nav>li>div");
nav_main.each(function(i){
$(this).mouseover(function(){
basic.show(i);
})
.mouseout(function(){
basic.hidden(i);
});
});
nav_child.each(function(i){
$(this).mouseover(function(){
basic.show(i);
})
.mouseout(function(){
basic.hidden(i);
});
});
var basic={
show:function(i){nav_child.eq(i).show();},
hidden:function(i){nav_child.eq(i).hide();}
}
</script>
查看效果:
HTML代码[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]
2. 增加一个小效果,菜单弹出的动画效果
程序代码var senior={
show:function(i){
nav_child.eq(i).show("fast");
},
hidden:function(i){
nav_child.eq(i).stop(true,true);
nav_child.eq(i).hide();
}
}
查看示例:
HTML代码[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]
3. 让菜单收缩也实现动画效果
程序代码var senior={
show:function(i){
nav_child.eq(i).show("fast");
},
hidden:function(i){
nav_child.eq(i).stop(true,true);
nav_child.eq(i).hide("fast");
}
}
查看示例:
HTML代码[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]
上面的效果看起来似乎还不够完美,应该让鼠标从子菜单上移走时,也是动画收回效果。
4. 进一步完善菜单的动画效果
运行查看效果:
HTML代码[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]
似乎还不够好,show和hidden函数写了两遍,分别在basic和senior对象里,能不能合成一个呢?
5. 再次进行改进,利用windows事件消除冒泡造成的菜单闪烁问题。
对senior对象进行改进:
程序代码getEvent:function(){
if(window.event){
return this.formatEvent(window.event);
}else{
return this.getEvent.caller.arguments[0];
}
},
formatEvent:function(e){
if(e.type=="mouseout"){
e.relatedTarget=e.toElement;
}else if(e.type=="mouseover"){
e.relatedTarget=e.fromElement;
}
e.stopPropagation=function(){this.cancelBubble=true;};
e.target=e.srcElement;
return e;
},
show:function(e,i){
nav_child.eq(i).stop(true,true);
var oEvent=this.getEvent();
if(oEvent.relatedTarget.tagName!='A'||$.inArray(oEvent.relatedTarget,nav_main)>-1){
nav_child.eq(i).show("fast");
}
},
hidden:function(e,i){
nav_child.eq(i).stop(true,true);
var oEvent=this.getEvent();
if(oEvent.relatedTarget.tagName!='A'||$.inArray(oEvent.relatedTarget,nav_main)>-1){
nav_child.eq(i).hide("fast");
}
}
}
查看示例效果:
HTML代码[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]
有了上面的模式之后,就可以很容易变换出其它的动画效果,比如把show换成slideDown,动画就变成了手风琴的效果,如下:
HTML代码[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]
只需要稍微修改一下CSS,就变成了横向菜单
HTML代码[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]
多行菜单
HTML代码Share your thoughts, post a comment.
Traction Theme by The Theme Foundry
Copyright © 2012 Hongbo Li. All rights reserved.

