YY流界面之动态图标导航栏
做这个导航栏的初衷,是想在公司产品的后台界面里,模仿MAC OS X系统的dock效果,所谓dock,就是OS X桌面底部那条显眼的工具栏,我的UBUNTU桌面里也有类似的效果……
实际上我也没用过MAC,所以是凭想象做的,演示页面在此:
http://www.ntrpg.org/yy/yy/demo/iconmenu.htm
右上角的导航栏是默认的效果,鼠标滑过时图标变大,会推挤旁边的图标。
下面第一排去掉了推挤效果。
第二排加入了左右移动的功能,图标的数量远远超出页面的宽度,只显示其中一部分,在导航栏上左右移动鼠标时,整个导航栏会向相反方向滑动,显示出隐藏的图标。
第三排把移动的操作改到了左右两侧的箭头,鼠标停留在箭头上时,导航栏就会向对应的方向滑动,鼠标离开箭头时滑动停止,当滑动到最末端的图标时,自动停止。
做这个导航栏的初衷,是想在公司产品的后台界面里,模仿MAC OS X系统的dock效果,所谓dock,就是OS X桌面底部那条显眼的工具栏,我的UBUNTU桌面里也有类似的效果……
实际上我也没用过MAC,所以是凭想象做的,演示页面在此:
http://www.ntrpg.org/yy/yy/demo/iconmenu.htm
右上角的导航栏是默认的效果,鼠标滑过时图标变大,会推挤旁边的图标。
下面第一排去掉了推挤效果。
第二排加入了左右移动的功能,图标的数量远远超出页面的宽度,只显示其中一部分,在导航栏上左右移动鼠标时,整个导航栏会向相反方向滑动,显示出隐藏的图标。
第三排把移动的操作改到了左右两侧的箭头,鼠标停留在箭头上时,导航栏就会向对应的方向滑动,鼠标离开箭头时滑动停止,当滑动到最末端的图标时,自动停止。
先实现导航栏的默认效果,HTML如下:
<!-- ICON menu -->
<div class="iconbarout">
<div id="iconbar0" class="iconbar" >
<ul style="margin-left:0px;">
<li>
<a href="#">
<img src="images/icon7.png" style="width:68px;height:68px;" onload="alphaPNG(this);" onmouseover="largeIcon(this);" onmouseout="reIcon(this);" />
<span>link7</span>
</a>
</li>
<li>
<a href="#">
<img src="images/icon6.png" style="width:68px;height:68px;" onload="alphaPNG(this);" onmouseover="largeIcon(this);" onmouseout="reIcon(this);" />
<span>link6</span>
</a>
</li>
</ul>
</div>
</div>
<!-- ICON menu end -->
为了追求立体感,图标不能有背景色,所以必须用透明PNG图片,这里用<img>标签插入图片,是因为要实现图标的缩小放大效果(CSS背景里的图片只能控制位置,不能改变大小),图标的长宽要写在元素的style属性里,方便JS程序控制。
由于IE6不支持PNG的透明背景,必须用滤镜来做HACK才能达到一样的效果,而滤镜只能写在CSS的背景属性里…………为了解决这个矛盾,就要依靠JS了:
function alphaPNG(png)
{
var aVersion=navigator.appVersion.split("MSIE");
var version=parseInt(aVersion[1]);
var pp=png.parentNode;
if( (version>=5.5) && (version<7) && (document.body.filters) )
{
var mout=png.onmouseout.toString();
var mover=png.onmouseover.toString();
alphaHTML="<span style=\"cursor:pointer;filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=scale, src='"+png.src+"');display:block;width:"+png.style.width+";height:"+png.style.height+";\" onmouseover=\""+mover.substring(mover.indexOf("{")+1,mover.lastIndexOf("}"))+"\" onmouseout=\""+mout.substring(mout.indexOf("{")+1,mout.lastIndexOf("}"))+"\" ></span>";
png.outerHTML=alphaHTML;
}
}
这个函数已经写在图片的onload事件里了,会在IMG标签的内容加载完后触发(这个事件虽好,也不能到处乱用,根据伟大的犀牛书V5,onload只支持body, frameset, img),函数先判断浏览器类型和版本(IE7支持透明PNG),先创建一个span元素,IMG标签的所有属性、事件都原样COPY到SPAN上,而PNG图片则放到SPAN的背景里,用滤镜处理成透明,注意滤镜属性里必须要有sizingMethod=scale。最后用outerHTML(只有IE支持)把该IMG替换成span。
导航栏的样式:
/* icon menu */
.iconbarout
{
width:770px;
position:absolute;
top:40px;right:10px;
}
.iconbar{
overflow:hidden;
float:left;
}
.iconbar li{
float:right;
padding:0px;
width:auto;
text-align:center;
margin:0 16px 0 0px;
}
.iconbar li span{
color:#333;
font-weight:600;
width:auto;
display:block;
float:none;
margin:0px auto;
}
.iconbar li a img{
margin:0px auto;
float:none;
}
.iconbar li a{
text-align:center;
float:none;
margin:0px auto;
}
.iconbar li img{
border:0px;
float:left;
}
这样就在IE和Firefox里实现一样的视觉效果了(这里存在一个问题,为了保证图标放大后的清晰度,初始的图标都是缩小的,在IE7和Firefox里都会看到一点锯齿,而IE6由于用了滤镜,缩小的图标边缘仍然是平滑的-_____-b)
接下来做鼠标滑过的放大缩小效果。JS的动画效果一般是利用setTimeout或setInterval的延迟功能,反复循环来实现的。为了避免这些图标在运行函数时发生冲突,我把缩放的动画效果封装到了一个类里:
/* zoom class by Dexter.Yy
********************************************************/
function animeZoom(ico,gWidth,gHeight,nWidth,nHeight)
{
this.png=ico;
this.iheight=nHeight;
this.iWidth=nWidth;
this.goWidth=gWidth;
this.goHeight=gHeight;
this.rico;
}
animeZoom.prototype.zoomEvent=function()
{
if(this.iWidth<this.goWidth)
{
this.goEnlarge();
}
else if(this.iWidth>this.goWidth)
{
this.goReduce();
}
}
animeZoom.prototype.goEnlarge=function()
{
this.png.style.width=this.goWidth+"px";
this.png.style.height=this.goWidth+"px";
}
animeZoom.prototype.goReduce=function()
{
var obj=this;
var h=parseInt(this.png.style.height);
var w=parseInt(this.png.style.width);
if(w>this.goWidth)
{
this.png.style.width=w-2+"px";
this.png.style.height=h-2+"px";
this.rico=setTimeout(function(){obj.goReduce();},30);
}
else
{
window.clearTimeout(this.rico);
}
}
使用时要传5个参数:目标对象、期望达到的宽度、期望达到的高度、原始宽度、原始高度,像这样:
function largeIcon(png)
{
var lIco=new animeZoom(png,91,91,68,68);
lIco.zoomEvent();
}
function reIcon(png)
{
var rIco=new animeZoom(png,68,68,91,91);
rIco.zoomEvent();
}
OK完工……如果是在FLASH里做这种推挤效果,可能还要写一大堆AS,但这里有CSS的浮动属性帮忙,就很省事……
作者: Dexter.Yy 发表于 3/03/2007 04:00:00 上午
标签: CODER
3 条评论:
请教一下:请问注释栏延迟淡出并呈现兰色是怎么弄的?
BLOG上的效果么,那个是用了现成的脚本,叫sweet-titles
实际上那不是注释栏,是把所有页面元素上的'title'属性移除,换成自定义的'tip'属性,然后加上鼠标滑过和滑出事件,触发事件时会生成了一个DIV显示在鼠标坐标上……不过在IE里运行速度很慢……
哦 原来如此,既然速度慢...就不弄了吧
发表评论