前段时间Discuz X1.5刚出来的时候,我做了一个简单的蓝色导航。但是不支持切换到宽版显示。今天抽时间改了一下,有点小心得,记录下来。

首先解释一下Discuz X1.5切换宽版的实现原理,它是通过一段JS脚本实现的。当用户点击该脚本时,会加载一个额外的CSS:widthauto.css。这个CSS文件将网站的框架.wp的宽度由970px修改为98%,这样就会自适应屏幕了。当然这个CSS文件里面还处理了其他的内容。比如我们接下来将要改动的导航。

改动前分析

首先看导航效果。这个导航有以下特点:

1、两头是有弧度的,中间是平铺的;

2、鼠标移动上去有改变;

3、每个导航文字有间隔分开,这个间隔只能用图片实现;

4、头部有个蓝色的背景;

再看一下DZ的htm模板:

可以看到,整个头部为hd,然后里面有个小的框架wp。再下面就是具体的模块了,有LOGO、导航等。

为了体现分离的思想,这里不修改DZ默认的模板,我们只改CSS。

窄版方案的制作

先只考虑窄版。窄版的算是很好做的,方法也很多,我一开始是这么做的。首先用CSS Sprite将所用用到的图片合在一起。然后呢,因为导航在窄版的情况下宽度固定,所以我直接在头部hdc这个div下将头部的图片和导航通过一个background一起实现了。然后鼠标移动的效果不用说了,简单的hover;导航文字之间的间隔,给li定义了一个背景,居右对齐即可。

背景图片:

效果实现了,但是这个方案还有很多缺点:

1、不支持切换到宽版。因为导航栏的背景图固定了,切换到宽版之后,导航背景图不够伸展。即使repeat-x了,也因为四个角的弧度导致不美观;

2、因为和头部的背景合在一起了,所以相当于头部固定住了,如果LOGO高度稍微高一些,撑开了头部,导致导航的背景图提上去了,不美观;

于是着手改造。

滑动门实现宽版适应

要想让导航能够随着屏幕的宽度自适应,首先想到的就是要让导航背景能够repeat,这是基本。那两边的圆角如何实现呢,首先就能够想到滑动门。实现方法就是,给#nv加个很长的背景和右侧的圆角,给#nv ul只用加左边的圆角就行了,这就是我们常见的两层滑动门,很多的圆角特效都是这么实现的。

如果只是用两层滑动门的话,那有一侧的滑动门的长度要足够长。到底多长呢。19寸宽屏就要1440,那更大的显示器呢?所以这样做的话,能够适应大部分的显示器,但是不能适应“更大”的显示器。

这样进一步想下去,既然不能适应更大的显示器,那干脆就不做那么长的滑动背景。再加一个Div,让他和nv这个层一样宽度,直接包裹在#nv的外面。然后给这个Div的background设置为水平重复的导航背景就OK了。

嗯,这确实是一个解决办法,但是有米有想过,这样做的话增加了一个Div不说(改动了HTML),还要增加新的图片,要增加一个重复背景的图片(其它图片sprite),相当于增加了一个额外的HTTP Request。

但是这个也不是一无是处的,这个最大的好处就是高度可以自适应了,不论你网站的LOGO多大,都可以。

改进的滑动门(我的实现方法)

接下来我介绍一下我自己的实现方法吧,虽然不是十全十美,但是不失为一种思路。

为了不修改HTML,体现分离思想,就自然要找把导航重复的背景放在哪儿。我仔细研究了一下这段HTML,头部的背景可以放在.hdc这个div里面,那#hd这个层就相当于空出来了。我为何不把重复的背景放在这里呢,正好导航是在#hd的最下面,只要定义background-position为0 100%就行了。

为了减少HTTP Request,我把这个头部所有用到的图片放在一起。如下所示(黑色的地方是透明背景)。

有同学看了就会问,这样放的话,#hd这个最大的div的背景在水平重复的时候,那导航背景上面的那些岂不是也会自动重复呢?那页面岂不是很乱?不用担心,给.hdc这个div定义background-color:#fff就可以把那些遮住了。

这样只要放置好了水平重复的导航背景,剩下的滑动门就好实现了。

但是这个方案也不是十全十美。

1、头部不能太高,太高的话,.hdc这个div的背景高度就不够了,就会露出下面的一些图片。解决办法也很简单,把这个背景独立出来就行了,但是增加了HTTP Request。还有一个不是完全适应所有需求的办法,就是强制给.hdc定义一个Max-height,使他不能过高。这样就可以重新设计css sprite了。当然这个max-height在IE 6下不支持。但是想一想,谁的LOGO会这么“高”呢?

2、点击导航链接的时候,或者刷新页面的时候,会发现.hdc背景有一些图片快速闪过后消失。这就是常说的闪屏现象。因为#hd定义的背景,多的部分是被.hdc的背景颜色遮住的,在加载页面的时候会有闪屏现象。解决办法,根据上面的max-height再重新制作一次css sprite图片,让重复的背景上面某个高度范围内是空的即可。图片如下所示:

好了,到此我们的效果基本上完全实现了,大家可以下载我的这个包到DZ X1.5的后台安装测试。

蓝色导航For Discuz X1.5