对于一个网站来讲均会存在公共页面,如异常页面、系统菜单等等,本章针对斗医系统菜单做一下介绍。可以想一想常见网站的系统菜单形式,一般都是菜单项在每个页面的内容不变,区别是菜单的选择状态不同。


JSP可以使用<%@ include file="">语句把公共系统菜单页面引进来,但本文不准备使用JSP,原因有两个:I、当服务器把HTTP请求的结果Response返回给客户端之前,需要把JSP先转换为HTML页面,然后再吐给客户端,这中间多了一个转换过程;II、随着WEB3.0的发展,JS的用武之地越来越多,本系统准备多使用一下JS。


同样HTML也可以通过<iframe>或<object>把页面引进来,本文亦不准备使用HTML的<iframe>引入菜单HTML页面,因为<iframe>对网站的性能有一定的损耗,同时在WEB安全方面存在通过<iframe>透骗用户的可能性。


【备注】:上面的说法并非十分严格,这些信息只是在实际工作中通过测试发现的。若对上面的个人观点感兴趣的话,大家可以在谷歌上搜索类似话题。



四、斗医公共系统菜单

1、实现思路

(1)HTML页面引用生成公共系统菜单的JS文件

(2)当HTML页面加载完后就调用JS的接口创建公共系统菜单,并根据当前页面设置菜单项的选中状态。这里面涉及到判读页面是否加载完的知识点,可以使用JS的onload(),也可以使用if(document.readyState=="complete"),两者在加载完成稍有区别。


2、导航菜单草图及菜单的作用

221525258.png

【搜索框】:可以搜索系统中相关的治疗医症的案例或相关医学高手

【下战书】:这是本系统的一个重点,之所以想叫斗医,也就是想有某个医学高手开出一个药方,里面讲明该药方治疗病症,及治疗原理,其他的医学高手可以对其进行点评,也可以给出其它的优于该药方的药方。这样可以起到一个相互探讨的目的

【首页】:顾名思义就是所有的医学药方的查看处

【专家】:后续可以把给出药方较好的人评价为专家,评价面要全面,可以升级为专家,也可以从专家队伍中剔除


3、目录规划

在斗医运行环境D:\medical\war下分别创建module、theme、js文件夹,其中module下放置HTML文件,用于显示页面内容;theme下放置图片和CSS文件,用于渲染页面样式;js下放置页面响应动作。其结构如下:

213519157.png


4、引入JQuery

伴随着JS的发展,很多优秀的JS工具都孕育而生,比如JQuery、SeaJs、underscorejs、NodeJs等等,关于JQuery的更多说明大家可以在51cto的博客上搜索到很多,此处不再赘述,就个人而言还是比较喜欢JQuery的便捷性,对于其UI组件(像表、树、日期、遮罩等)建议读其源码而非直接使用。

从JQuery官网http://jquery.com/download/下载后放置到D:\medical\war\js\common下,把其命名为jquery.js


【备注】:我下载的是2.0.3未压缩版本,之所以选择未压缩主要是为后面看源码方便;把jquery_2.0.3.jar命名为jquery.js是为了引用时少写版本号,此处意义不大。



5、页面写作之前的话

(1)写一个网站一定要清楚这个网站的定位,否则既便做的很漂亮、性能很好,网站也无法长久生存,这点是做网站应用的前提条件。此斗医系统是我当初的心血来潮,主要是为了练手用的,所以其定位见上面《导航菜单草图及菜单的作用》。

(2)曾看过一本关于CSS的书《别具光芒 CSS网页布局案例剖析》,里面讲到如何写一个页面:先不管它的展显形式,先把内容填写进去,然后使用CSS对其进行装饰。

(3)W3C在制定HTML5规范时有一句话讲的很好,在此分享一下:HTML文件只负责显示内容,CSS只负责内容的展显方式。

关于网页方面的知识,可以问一下谷歌,肯定存在不少人才,会把上面看似无关联的话题清晰地讲出来。


6、导航菜单实现过程

(1)在D:\medical\war\module\navigation下创建navigation.html文件(编码格式为UTF-8),内容如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!doctype html>
< html >
     < head >
         < title >medical</ title >
         < link  rel = "stylesheet"  type = "text/css"  href = "../../theme/navigation/navigation.css" >
     </ head >
     < body >
         < div  class = "system_menu" >
             < div  class = "system_menu_wrapper" >
                 < div  class = "system_menu_search" >
                     < input  type = "text"  id = "system_menu_searcher" >
                 </ div >
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
                 < div  class = "system_menu_item" >
                     < ul >
                         < li >< a  href = "#" >下战书</ a ></ li >
                         < li >< a  href = "#" >首页</ a ></ li >
                         < li >< a  href = "#" >专家</ a ></ li >
                     </ ul >
                 </ div >
                 < div  class = "system_menu_user" >
                     < div  class = "system_menu_user_wrapper" >
                         < a  href = "#" >< i ></ i >< span >陈许诺</ span ></ a >
                     </ div >
                     < div  class = "system_menu_user_setting" >
                         < ul >
                             < li >< i  class = "system_menu_user_setting_home" ></ i >< span >主页</ span ></ li >
                             < li >< i  class = "system_menu_user_setting_set" ></ i >< span >设置</ span ></ li >
                             < li >< i  class = "system_menu_user_setting_exit" ></ i >< span >退出</ span ></ li >
                         </ ul >
                     </ div >
                 </ div >
             </ div >
         </ div >
     </ body >
</ html >



【备注】:从这个文件中可以看到对于标签定义了class。有人问你怎么知道这样定义内容和样式?我只能回答:因这是我实现了的,所以我知道这样做。其实这里面有一个“量变”的积累过程,写20多个页面之后自然就清楚了,解释起来真说不清楚。



(2)在D:\medical\war\theme\navigation下创建navigation.css文件(编码格式为UTF-8),此时用浏览器打开navigation.html文件,其内容如下:

232432957.png


下面我们用CSS把其打扮的漂亮一些,navigation.css中先定义如下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
body, input, a, ul{
     font-family 'Helvetica Neue' , Helvetica , Arial , Sans-serif ;
     font-size 14px ;
     margin 0px ;
     padding 0px ;
}
/*
  * 去掉前面圆点
  */
ul{
     list-style none ;
}
/**
  * 去掉下划线
  */
a{
     text-decoration none ;
}

这些都是全局性质的样式定义,其作用如注释所示,浏览器打开navigation.html文件效果如下:

232330489.png


(3)使搜索框、菜单项、用户设置都在一行显示

缺省情况下div的宽度都是当前屏幕的宽度,所以定义多个div时都是上下并列的,这也是上图上看到的搜索框、菜单项(显示为蓝色部分)、用户设置(蓝色字体的下面部分)都是上下并列的。我们在navigation.css中追加下面内容:

1
2
3
4
5
6
7
8
9
10
11
/*
  * 搜索框、菜单项、用户项均浮动
  */
.system_menu_search, .system_menu_item{
     float left ;
}
.system_menu_user{
     float right ;
     width 120px ;
     height : inherit;
}

其内容样式变为如下效果:

233259882.png

(4)设置菜单项背景为蓝色,高度固定为50像素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
  * 斗医系统导航菜单
  */
.system_menu{
     height 50px ;
     width 100% ;
     background-color #0767c8 ;
     margin 0px ;
}
/*
  * 系统菜单包裹层高度与父同高,且居中显示
  */
.system_menu_wrapper{
     margin 0  auto ;
     height : inherit;
     width 960px ;
     clear both ;
}


【备注】:这里的clear:both是一个知识点,它的作用是当它的孩子元素设置为浮动时,会从该元素的标准流中脱离出来,它的高度就与孩子高度无关了,为了让它照样看起来像包含着孩子元素,就需要设置clear:both,有兴趣的可以读一下《【CSS】【10】CSS盒子clear属性和高度



(5)美化全局搜索框

1
2
3
4
5
6
7
8
9
10
11
.system_menu_search input{
     width 360px ;
     height 36px ;
     border 1px  solid  #045BB3 ;
     border-radius:  4px ;
     /*使<input>垂直居中*/
     margin-top 7px ;
     margin-bottom 7px ;
     /*在chrome浏览器下去掉<input>焦点时的外边框*/
     outline none ;
}

这里把搜索框的高度设置为36像素,宽度设置为360像素,同时有4个像素的圆角,不过需要注意的是border-radius在IE8下不起作用,这里不再处理兼容问题了,大家可以在谷歌上搜索CSS圆角,有很多关于兼容的解决方案。设置后的效果如下:

234929439.png(6)从上图看菜单项(下战书、首页和专家)貌似看不到了,那接下来就美化一下它们的显示效果,在navigation.css中追加如下CSS代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
  * 系统菜单项设置
  */
.system_menu_item ul{
     height 50px ;
     line-height 50px ;
     margin-left 15px ;
}
.system_menu_item li{
     float left ;
     width 50px ;
     margin auto  8px ;
     text-align center ;
}
.system_menu_item li:hover{
     background-color #ff901d ;
}
.system_menu_item a, .system_menu_user_wrapper a{
     color #FFF ;
}

该CSS设置后的效果是菜单项是白色字体,菜单文本都是居中显示,且菜单项之间有间隔,当鼠标放到菜单项上时背景色变为棕***,效果图如下:

235517143.png

(7)先下载两个图片以备后面使用:把下载后的navigation.png放置到D:\medical\war\theme\navigation下面;把default.jpg放置到D:\medical\war\upload\default下面。在设置用户CSS样式之前,再熟悉一下用户的HTML结构:

000347109.png

在每个<span>之前都有一个<i>标签,里面内容为空,它的作用是设置图标用的。在navigation.css追加如下CSS让<i>、<span>元素浮动起来:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
  * 系统用户菜单项设置
  */
.system_menu_user{
     float right ;
     width 120px ;
     height : inherit;
}
.system_menu_user_wrapper{
     width : inherit;
     height : inherit;
     line-height 50px ;
}
.system_menu_user_wrapper i, .system_menu_user_wrapper span{
     float left ;
}
.system_menu_user_wrapper i, .system_menu_user_wrapper span, .system_menu_user_setting_home, .system_menu_user_setting_set, .system_menu_user_setting_exit, .system_menu_user_setting span{
     float left ;
}
.system_menu_user_wrapper span, .system_menu_user_setting span{
     width 83px ;
     text-align center ;
}


此时除了“用户名”垂直居中显示之外(因为.system_menu_user_wrapper的line-height值设置与父div高度相同),其它的都看不出来变化。下面再设置.system_menu_user_wrapper i把用户的头像显示出来

1
2
3
4
5
6
7
8
9
10
11
12
/*头像样式*/
.system_menu_user_wrapper i{
     width 27px ;
     height 27px ;
     /*若无属性背景图片无法显示*/
     display : inline- block ;
     background-image url (../../upload/ default / default .jpg);
     background-repeat no-repeat ;
     /*居中显示*/
     margin-top 12px ;
     margin-left 10px ;
}


效果图如下:

002130160.png

(8)当鼠标放置在用户和头像菜单上时也希望背景色变为棕***

1
2
3
4
/*鼠标放置在用户菜单上时背景色变为棕****/
.system_menu_user_wrapper:hover, .system_menu_user_setting li:hover{
     background-color #ff901d ;
}

002500728.png

(9)最后按此思路设置用户设置的其它菜单项,在navigation.css中追加CSS,其效果图如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
system_menu_user_setting li{
     height 40px ;
     line-height 40px ;
     background-color #095FB3 ;
     color #FFF ;
     border-top 1px  solid  #0D5AA5
}
.system_menu_user_setting_home, .system_menu_user_setting_set, .system_menu_user_setting_exit{
     width 20px ;
     height 20px ;
     /*若无属性背景图片无法显示*/
     display : inline- block ;
     background-image url (navigation.png);
     background-repeat no-repeat ;
     /*居中显示*/
     margin-top 10px ;
     margin-left 17px ;
}
.system_menu_user_setting span{
     width 83px ;
     text-align center ;
}
.system_menu_user_setting_home{
     background-position -6px  -7px ;
}
.system_menu_user_setting_set{
     background-position -6px  -60px ;
}
.system_menu_user_setting_exit{
     background-position -6px  -87px ;
}

002906358.png


(10)缺省情况下我们希望用户菜单项下面的子元素(主页、设置、退出)不显示,只有当鼠标放置到用户菜单项时子元素才显示出来。

1
2
3
.system_menu_user_setting{
     display none ;
}


7、在第6步中通过HTML和CSS演示把菜单项绘制出来了,正如该文开头所说,我们希望这个菜单项是公用的,所以想通过JS生成此菜单,并把此菜单引入到每个页面中。

(1)在D:\medical\war\js\common下创建common.js文件,由于考虑到这是一个公共工具类,所以没有采用闭包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
  * 生成系统公共菜单
  */
function  generateSystemMenu()
{
     var  systemMenu =  '<div class="system_menu">' ;
     systemMenu    +=      '<div class="system_menu_wrapper">' ;
                                                                        
     systemMenu    +=          '<div class="system_menu_search">' ;
     systemMenu    +=              '<input type="text" id="system_menu_searcher">' ;
     systemMenu    +=          '</div>' ;
     systemMenu    +=          '<div class="system_menu_item">' ;
     systemMenu    +=              '<ul>' ;
     systemMenu    +=                  '<li><a href="#">下战书</a></li>' ;
     systemMenu    +=                  '<li><a href="#">首页</a></li>' ;
     systemMenu    +=                  '<li><a href="#">专家</a></li>' ;
     systemMenu    +=              '</ul>' ;
     systemMenu    +=          '</div>' ;
     systemMenu    +=          '<div class="system_menu_user">' ;
     systemMenu    +=              '<div class="system_menu_user_wrapper">' ;
     systemMenu    +=                  '<a href="#"><i></i><span>陈许诺</span></a>' ;
     systemMenu    +=              '</div>' ;
     systemMenu    +=              '<div class="system_menu_user_setting">' ;
     systemMenu    +=                  '<ul>' ;
     systemMenu    +=                      '<li><i class="system_menu_user_setting_home"></i><span>主页</span></li>' ;
     systemMenu    +=                      '<li><i class="system_menu_user_setting_set"></i><span>设置</span></li>' ;
     systemMenu    +=                      '<li><i class="system_menu_user_setting_exit"></i><span>退出</span></li>' ;
     systemMenu    +=                  '</ul>' ;
     systemMenu    +=              '</div>' ;
     systemMenu    +=          '</div>' ;
     systemMenu    +=      '</div>' ;
     systemMenu    +=  '</div>' ;
     $(systemMenu).appendTo($( "#system_navigation_menu" ));
}


(2)修改D:\medical\war\module\login\login.html文件,首先引入navigation.css样式文件,其次再引入jquery.jscommon.jslogin.js文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!DOCTYPE HTML>
< html >
     < head >
         < title >medical</ title >
         < link  rel = "stylesheet"  type = "text/css"  href = "theme/navigation/navigation.css" >
         < script  src = "js/common/jquery.js" ></ script >
         < script  src = "js/common/common.js" ></ script >
         < script  src = "js/login/login.js" ></ script >
     </ head >
     < body >
         < div  id = "system_navigation_menu" >
         </ div >
         < div >
             < h1 >This is Login page!</ h1 >
         </ div >
     </ body >
</ html >


【备注】:在引用css和js文件时,一定要谨记文件的相对路径是相对web应用环境的,即我们的D:\medical\war



(3)创建D:\medical\war\js\login\login.js文件,这里使用jqueryready方法来判断页面是否加载完,若加载完就调用common.js的生成菜单方法,把菜单追加到login.html<div>

1
2
3
4
5
6
( function ( window){
     $(document).ready( function ()
     {
         generateSystemMenu();
     });
})( window );


8、启动tomcat服务,在浏览器中输入http://localhost:8080/medical查看效果,会发现菜单已生成:

013502668.png



【备注】


(1)关于CSS样式一定要多写才能理解其含义,在写的过程中就像一个雕刻艺术家一凿凿地打磨,这个过程是痛并快乐的。

(2)上面写的navigation.html只是方便调试样式使用的,真正使用的是JS生成的导航菜单。