菜单是web开发中常见的功能模块,它能够直观的展示给用户本站中有哪些功能。一般在页面中看到的菜单类型分为两种:横向菜单和纵向菜单。
今天分别来完成纵向菜单和横向菜单的功能。先来看看纵向菜单,首先导航栏有四个菜单项,分别是古典名著《红楼梦》、《水浒传》、《三国演义》、《西游记》,而每个菜单栏下面分别对应着自己的二级菜单。对应的html是一个无序列表ul下面的四个li,每个li包括了每个一级菜单和一级菜单下的二级菜单。对应的html如下:
<body>
<ul>
<li class="main">
红楼梦
<ul>
<li>第一回 甄士隐梦幻识通灵 贾雨村风尘怀闺秀li>
<li>第二回 贾夫人仙逝扬州城 冷子兴演说荣国府li>
<li>第三回 金陵城起复贾雨村 荣国府收养林黛玉li>
<li>第四回 薄命女偏逢薄命郎 葫芦僧乱判葫芦案li>
<li>第五回 开生面梦演红楼梦 立新场情传幻境情li>
ul>
li>
<li class="main">
水浒传
<ul>
<li>第一回 张天师祈禳瘟疫 洪太尉误走妖魔li>
<li>第二回 王教头私走延安府 九纹龙大闹史家村li>
<li>第三回 史大郎夜走华阴县 鲁提辖拳打镇关西li>
<li>第四回 赵员外重修文殊院 鲁智深大闹五台山li>
<li>第五回 小霸王醉入销金帐 花和尚大闹桃花村li>
ul>
li>
<li class="main">
三国演义
<ul>
<li>第一回 宴桃园豪杰三结义 斩黄巾英雄首立功li>
<li>第二回 张翼德怒鞭督邮 何国舅谋诛宦竖li>
<li>第三回 议温明董卓叱丁原 馈金珠李肃说吕布li>
<li>第四回 废汉帝陈留践位 谋董贼孟德献刀li>
<li>第五回 发矫诏诸镇应曹公 破关兵三英战吕布li>
ul>
li>
<li class="main">
西游记
<ul>
<li>第一回 靈根育孕源流出 心性修持大道生li>
<li>第二回 悟徹菩提真妙理 斷魔歸本合元神li>
<li>第三回 四海千山皆拱伏 九幽十類盡除名li>
<li>第四回 官封弼馬心何足 名注齊天意未寧li>
<li>第五回 亂蟠桃大聖偷丹 反天宮諸神捉怪li>
ul>
li>
ul>
body>
我们是用列表嵌套列表的方式来做二级菜单的,如果再有三级菜单,只需要在二级菜单的li中再添加一层ul。上诉html代码的页面效果如下:
显然离想要的效果相去甚远。这时候可以用menu.css来控制想要的效果。浏览器中ul和li元素默认情况下文字前都有圆点标识符,li元素会有缩进。去掉ul和li的前面的圆点可以用如下的样式:
ul, li {
list-style: none;
}
清除子菜单的缩进值
ul {
padding: 0;
margin: 0;
}
要想把一级菜单的导航栏背景颜色设置为黑色,使用background-image来完成这一需求。如果背景图片比元素的实际大小要小,那么背景图就会自动在横向和纵向上重复显示,直到充满整个区域。这时候需要用background-repeat来控制背景图的重复填充方式。
.main {
background-image: url("../image/title.gif");
background-repeat: repeat-x;
width: 360px;
}
需要指出的是,背景图片的url内容是图片的相对位置,background-repeat和width配合起来是让图片在360个像素长度的区域横向重复。如果一个元素上同时定义了背景图和背景色,那么有背景图的地方是不会显示背景色的。
接下来给菜单栏的内容加上a标签。同时为了能够显示其手指图标,样式如下:
a {
/*取消所有的下划线*/
text-decoration: none;
padding-left: 20px;
display: block;
display: inline-block;
width: 340px;
padding-top: 3px;
padding-bottom: 3px;
}
.main a {
color: white;
background-image: url(../image/collapsed.gif);
background-repeat: no-repeat;
background-position: 2px center;
}
.main li a {
color: black;
background: none;
}
li {
background-color: #EEEEEE;
}
text-decoration属性值为none时,可以取消文字上的下划线,background-position可以控制背景图的位置,属性值既可以用数值,也可以用center,left,top这些值来控制横向和纵向的位置。这个属性的两个值,第一个对应横向,第二个对应纵向。background-image的值为none表示没有背景图片。.main a中的color为白色,.main li a中的color为黑色目的是为了让一级菜单黑底白字,而二级菜单是白底黑字。页面效果如图:
页面渲染的差不多了,接下来是做隐藏二级菜单的功能。首先在前面的css中默认所有控制二级菜单的为none,也就是不显示的。
.main ul {
display: none;
}
然后用jquery的选择器选出所有的一级菜单标题来控制对应二级菜单的显示和隐藏。
$(document).ready(function() {
$(".main > a").click(function() {
var ulNode = $(this).next("ul");
//让二级菜单显示和隐藏
if(ulNode.css("display") == "block") {
ulNode.css("display", "none");
} else {
ulNode.css("display", "block");
}
changeIcon($(this));
});
});
.main a和.main>a的不同之处,前者选择了用.main的这个class的元素内部所有的a节点,候着只选择.main的子节点中的a节点。隐藏和显示效果,在jQuery中的实现方式比较多,这里介绍几种。
在一级菜单的左边有一个白色的按钮。当二级菜单展开的时候按钮指向右,当二级菜单收缩的时候按钮指向下。实现这样的效果需要障眼法,当出发点击事件时,不停的切换向右箭头和向下箭头的图片。
function changeIcon(menuNode) {
if(-1 != menuNode.css("background-image").indexOf("collapsed.gif")) {
menuNode.css("background-image", "url('../image/expanded.gif')");
} else {
menuNode.css("background-image", "url('../image/collapsed.gif')");
}
}
这里用到js的函数indexOf()的用法
定义和用法
indexOf() 方法可返回某个指定的字符串值在字符串中首次出现的位置。
语法
stringObject.indexOf(searchvalue,fromindex)参数 描述
searchvalue 必需。规定需检索的字符串值。
fromindex 可选的整数参数。规定在字符串中开始检索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略该参数,则将从字>符串的首字符开始检索。
说明
该方法将从头到尾地检索字符串 stringObject,看它是否含有子串 searchvalue。开始检索的位置在字符串的 fromindex 处或字符串的开头
(没有指定 fromindex 时)。如果找到一个 searchvalue,则返回 searchvalue 的第一次出现的位置。stringObject 中的字符位置是从 0 >开始的。
该函数的处理过程是jQuery拿到一级菜单的节点,然后判断背景图片的url地址是否包含字符串“collapsed.gif”,如果包含则切换到expaned.gif,如果不包含则切换到collapsed.gif。
调用方式是:
$(".main > a").click(function() {
changeIcon($(this));
});
到此,纵向菜单功能已经基本实现,横向菜单的做法也是差不多的,最关键的地方是让ul的四个li横向展示。css中的关键代码是”float: left;”。html代码与纵向菜单相同
<ul>
<li class="hmain">
<a href="#">红楼梦a>
<ul>
<li><a href="#">第一回 甄士隐梦幻识通灵 贾雨村风尘怀闺秀a>li>
<li><a href="#">第二回 贾夫人仙逝扬州城 冷子兴演说荣国府a>li>
<li><a href="#">第三回 金陵城起复贾雨村 荣国府收养林黛玉a>li>
<li><a href="#">第四回 薄命女偏逢薄命郎 葫芦僧乱判葫芦案a>li>
<li><a href="#">第五回 开生面梦演红楼梦 立新场情传幻境情a>li>
ul>
li>
<li class="hmain">
<a href="#">水浒传a>
<ul>
<li><a href="#">第一回 张天师祈禳瘟疫 洪太尉误走妖魔a>li>
<li><a href="#">第二回 王教头私走延安府 九纹龙大闹史家村a>li>
<li><a href="#">第三回 史大郎夜走华阴县 鲁提辖拳打镇关西a>li>
<li><a href="#">第四回 赵员外重修文殊院 鲁智深大闹五台山a>li>
<li><a href="#">第五回 小霸王醉入销金帐 花和尚大闹桃花村a>li>
ul>
li>
<li class="hmain">
<a href="#">三国演义a>
<ul>
<li><a href="#">第一回 宴桃园豪杰三结义 斩黄巾英雄首立功a>li>
<li><a href="#">第二回 张翼德怒鞭督邮 何国舅谋诛宦竖a>li>
<li><a href="#">第三回 议温明董卓叱丁原 馈金珠李肃说吕布a>li>
<li><a href="#">第四回 废汉帝陈留践位 谋董贼孟德献刀a>li>
<li><a href="#">第五回 发矫诏诸镇应曹公 破关兵三英战吕布a>li>
ul>
li>
ul>
在menu.css中,控制.main的样式统统用来控制.hmain,除此之外还应该添加横向飘逸的这一句:
.hmain {
float: left;
margin-left: 1px;
}
而横向菜单的二级菜单的展开与收缩与纵向不同,横向菜单当鼠标进入区域时展开内容,当鼠标离开时内容收缩。这里用到jQuery的hover()方法。
.hover( handlerIn, handlerOut )
Description: Bind two handlers to the matched elements, to be executed when the mouse pointer enters and leaves the elements.
.hover(handlerIn, handlerOut)
描述:
将两个处理程序绑定到匹配的元素,当鼠标指针进入并离开元素时执行。
实现的代码如下:
$(".hmain").hover(function(){
$(this).children("ul").toggle("slow");
// $(this).children("ul").slideDown("3000");
changeIcon($(this).children("a"));
},function(){
$(this).children("ul").toggle("slow");
// $(this).children("ul").slideUp("3000");
changeIcon($(this).children("a"));
});
当鼠标进入横向菜单一级菜单时,代码执行进入hover()函数里面的第一个函数,触发toggle()函数,然后调用之前写好的改变箭头状态的changeIcon函数。当鼠标离开的时候代码执行进入hover()函数里面的第二个函数,触发toggle()函数,然后调用changeIcon函数。
代码参考地址:https://github.com/shizongger/JqueryInAction
参考资料:
1. 王兴奎《jQuery实战》
2. w3school