流界面之动态图标导航栏

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

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

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

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

  1. <div class="iconbarout">
  2.  
  3. <div id="iconbar0" class="iconbar" >
  4.  
  5.  <ul style="margin-left:0px;">
  6.  
  7.  <li>
  8.   <a href="#">
  9.  
  10.    <img src="images/icon7.png" style="width:68px;height:68px;" onload="alphaPNG(this);" onmouseover="largeIcon(this);" onmouseout="reIcon(this);" />
  11.  
  12.    <span>link7</span>
  13.   </a>
  14.  </li>
  15.  
  16.  
  17.  <li>
  18.   <a href="#">
  19.  
  20.    <img src="images/icon6.png" style="width:68px;height:68px;" onload="alphaPNG(this);" onmouseover="largeIcon(this);" onmouseout="reIcon(this);" />
  21.  
  22.    <span>link6</span>
  23.   </a>
  24.  </li>
  25.  
  26.  
  27.  </ul>
  28. </div>
  29.  
  30.  
  31. </div>

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

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

  1. function alphaPNG(png)
  2. {
  3. var aVersion=navigator.appVersion.split("MSIE");
  4.  
  5. var version=parseInt(aVersion[1]);
  6. var pp=png.parentNode;
  7.  
  8. if( (version>=5.5) && (version<7) && (document.body.filters) )
  9.  
  10. {
  11.  var mout=png.onmouseout.toString();
  12.  
  13.  var mover=png.onmouseover.toString();
  14.  
  15.  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+";/" οnmοuseοver=/""+mover.substring(mover.indexOf("{")+1,mover.lastIndexOf("}"))+"/" οnmοuseοut=/""+mout.substring(mout.indexOf("{")+1,mout.lastIndexOf("}"))+"/" ></span>";
  16.  
  17.  png.outerHTML=alphaHTML;
  18. }
  19.  
  20. }

这个函数已经写在图片的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.  
  5. position:absolute;
  6. top:40px;right:10px;
  7.  
  8. }
  9.  
  10. .iconbar{
  11. overflow:hidden;
  12. float:left;
  13.  
  14. }
  15.  
  16. .iconbar li{
  17. float:right;
  18. padding:0px;
  19.  
  20. width:auto;
  21. text-align:center;
  22. margin:0 16px 0 0px;
  23.  
  24. }
  25. .iconbar li span{
  26. color:#333;
  27. font-weight:600;
  28.  
  29. width:auto;
  30. display:block;
  31. float:none;
  32.  
  33. margin:0px auto;
  34. }
  35. .iconbar li a img{
  36. margin:0px auto;
  37.  
  38. float:none;
  39. }
  40. .iconbar li a{
  41. text-align:center;
  42.  
  43. float:none;
  44. margin:0px auto;
  45. }
  46. .iconbar li img{
  47.  
  48. border:0px;
  49. float:left;
  50. }

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

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

  1. /* zoom class by Dexter.Yy
  2. ********************************************************/
  3.  
  4. function animeZoom(ico,gWidth,gHeight,nWidth,nHeight)
  5.  
  6. {
  7. this.png=ico;
  8. this.iheight=nHeight;
  9.  
  10. this.iWidth=nWidth;
  11. this.goWidth=gWidth;
  12. this.goHeight=gHeight;
  13.  
  14. this.rico;
  15. }
  16.  
  17. animeZoom.prototype.zoomEvent=function()
  18.  
  19. {
  20. if(this.iWidth<this.goWidth)
  21. {
  22.  this.goEnlarge();
  23.  
  24. }
  25. else if(this.iWidth>this.goWidth)
  26. {
  27.  
  28.  this.goReduce();
  29. }
  30.  
  31. }
  32.  
  33. animeZoom.prototype.goEnlarge=function()
  34.  
  35. {
  36. this.png.style.width=this.goWidth+"px";
  37.  
  38. this.png.style.height=this.goWidth+"px";
  39.  
  40. }
  41.  
  42. animeZoom.prototype.goReduce=function()
  43. {
  44. var obj=this;
  45.  
  46. var h=parseInt(this.png.style.height);
  47.  
  48. var w=parseInt(this.png.style.width);
  49.  
  50. if(w>this.goWidth)
  51. {
  52.  this.png.style.width=w-2+"px";
  53.  
  54.  this.png.style.height=h-2+"px";
  55.  
  56.  this.rico=setTimeout(function(){obj.goReduce();},30);
  57.  
  58. }
  59. else
  60. {
  61.  window.clearTimeout(this.rico);
  62.  
  63. }
  64. }

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

  1. function largeIcon(png)
  2. {
  3. var lIco=new animeZoom(png,91,91,68,68);
  4.  
  5. lIco.zoomEvent();
  6. }
  7.  
  8. function reIcon(png)
  9.  
  10. {
  11. var rIco=new animeZoom(png,68,68,91,91);
  12.  
  13. rIco.zoomEvent();
  14. }

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

 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值