流界面之动态图标导航栏

做这个导航栏的初衷,是想在公司产品的后台界面里,模仿MAC OS X系统的dock效果,所谓dock,就是OS X桌面底部那条显眼的工具栏,我的UBUNTU桌面里也有类似的效果……

实际上我也没用过MAC,所以是凭想象做的,演示页面在此

右上角的导航栏是默认的效果,鼠标滑过时图标变大,会推挤旁边的图标。
下面第一排去掉了推挤效果。
第二排加入了左右移动的功能,图标的数量远远超出页面的宽度,只显示其中一部分,在导航栏上左右移动鼠标时,整个导航栏会向相反方向滑动,显示出隐藏的图标。
第三排把移动的操作改到了左右两侧的箭头,鼠标停留在箭头上时,导航栏就会向对应的方向滑动,鼠标离开箭头时滑动停止,当滑动到最末端的图标时,自动停止。

先实现导航栏的默认效果,HTML如下:

  1. <div class="iconbarout">
  2. <divid="iconbar0" class="iconbar" >
  3. <ul style="margin-left:0px;">
  4. <li>
  5. <ahref="#">
  6. <imgsrc="images/icon7.png" style="width:68px;height:68px;" onload="alphaPNG(this);" onmouseover="largeIcon(this);" onmouseout="reIcon(this);" />
  7. <span>link7</span>
  8. </a>
  9. </li>
  10. <li>
  11. <ahref="#">
  12. <imgsrc="images/icon6.png" style="width:68px;height:68px;" onload="alphaPNG(this);" onmouseover="largeIcon(this);" onmouseout="reIcon(this);" />
  13. <span>link6</span>
  14. </a>
  15. </li>
  16. </ul>
  17. </div>
  18. </div>

为了追求立体感,图标不能有背景色,所以必须用透明PNG图片,这里用<img>标签插入图片,是因为要实现图标的缩小放大效果(CSS背景里的图片只能控制位置,不能改变大小),图标的长宽要写在元素的style属性里,方便JS程序控制。

由于IE6不支持PNG的透明背景,必须用滤镜来做HACK才能达到一样的效果,而滤镜只能写在CSS的背景属性里…………为了解决这个矛盾,就要依靠JS了:

  1. function alphaPNG(png)
  2. {
  3. varaVersion=navigator.appVersion.split("MSIE");
  4. varversion=parseInt(aVersion[1]);
  5. varpp=png.parentNode;
  6. if((version>=5.5) && (version<7) && (document.body.filters) )
  7. {
  8. var mout=png.onmouseout.toString();
  9. var mover=png.onmouseover.toString();
  10. 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>";
  11. png.outerHTML=alphaHTML;
  12. }
  13. }

这个函数已经写在图片的onload事件里了,会在IMG标签的内容加载完后触发(这个事件虽好,也不能到处乱用,根据伟大的犀牛书V5, onload只支持body, frameset, img),函数先判断浏览器类型和版本(IE7支持透明PNG),先创建一个span元素,IMG标签的所有属性、事件都原样COPY到SPAN上,而 PNG图片则放到SPAN的背景里,用滤镜处理成透明,注意滤镜属性里必须要有sizingMethod=scale。最后用outerHTML(只有 IE支持)把该IMG替换成span。

导航栏的样式:

  1. .iconbarout
  2. {
  3. width:770px;
  4. position:absolute;
  5. top:40px;right:10px;
  6. }
  7. .iconbar{
  8. overflow:hidden;
  9. float:left;
  10. }
  11. .iconbarli{
  12. float:right;
  13. padding:0px;
  14. width:auto;
  15. text-align:center;
  16. margin:016px 0 0px;
  17. }
  18. .iconbarli span{
  19. color:#333;
  20. font-weight:600;
  21. width:auto;
  22. display:block;
  23. float:none;
  24. margin:0pxauto;
  25. }
  26. .iconbarli a img{
  27. margin:0pxauto;
  28. float:none;
  29. }
  30. .iconbarli a{
  31. text-align:center;
  32. float:none;
  33. margin:0pxauto;
  34. }
  35. .iconbarli img{
  36. border:0px;
  37. float:left;
  38. }

这样就在IE和Firefox里实现一样的视觉效果了(这里存在一个问题,为了保证图标放大后的清晰度,初始的图标都是缩小的,在IE7和Firefox里都会看到一点锯齿,而IE6由于用了滤镜,缩小的图标边缘仍然是平滑的-_____-b)

接下来做鼠标滑过的放大缩小效果。JS的动画效果一般是利用setTimeout或setInterval的延迟功能,反复循环来实现的。为了避免这些图标在运行函数时发生冲突,我把缩放的动画效果封装到了一个类里:

  1. /* zoom class by Dexter.Yy
  2. ********************************************************/
  3. functionanimeZoom(ico,gWidth,gHeight,nWidth,nHeight)
  4. {
  5. this.png=ico;
  6. this.iheight=nHeight;
  7. this.iWidth=nWidth;
  8. this.goWidth=gWidth;
  9. this.goHeight=gHeight;
  10. this.rico;
  11. }
  12. animeZoom.prototype.zoomEvent=function()
  13. {
  14. if(this.iWidth<this.goWidth)
  15. {
  16. this.goEnlarge();
  17. }
  18. elseif(this.iWidth>this.goWidth)
  19. {
  20. this.goReduce();
  21. }
  22. }
  23. animeZoom.prototype.goEnlarge=function()
  24. {
  25. this.png.style.width=this.goWidth+"px";
  26. this.png.style.height=this.goWidth+"px";
  27. }
  28. animeZoom.prototype.goReduce=function()
  29. {
  30. varobj=this;
  31. varh=parseInt(this.png.style.height);
  32. varw=parseInt(this.png.style.width);
  33. if(w>this.goWidth)
  34. {
  35. this.png.style.width=w-2+"px";
  36. this.png.style.height=h-2+"px";
  37. this.rico=setTimeout(function(){obj.goReduce();},30);
  38. }
  39. else
  40. {
  41. window.clearTimeout(this.rico);
  42. }
  43. }

使用时要传5个参数:目标对象、期望达到的宽度、期望达到的高度、原始宽度、原始高度,像这样:

  1. function largeIcon(png)
  2. {
  3. varlIco=new animeZoom(png,91,91,68,68);
  4. lIco.zoomEvent();
  5. }
  6. functionreIcon(png)
  7. {
  8. varrIco=new animeZoom(png,68,68,91,91);
  9. rIco.zoomEvent();
  10. }

OK完工……如果是在FLASH里做这种推挤效果,可能还要写一大堆AS,但这里有CSS的浮动属性帮忙,就很省事……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值