论坛交流
首页办公自动化| 网页制作| 平面设计| 动画制作| 数据库开发| 程序设计| 全部视频教程
应用视频: Windows | Word2007 | Excel2007 | PowerPoint2007 | Dreamweaver 8 | Fireworks 8 | Flash 8 | Photoshop cs | CorelDraw 12
编程视频: C语言视频教程 | HTML | Div+Css布局 | Javascript | Access数据库 | Asp | Sql Server数据库Asp.net  | Flash AS
当前位置 > 文字教程 > Javascript教程
Tag:验证,特效,入门,实例,验证,表单,特效,正则表达式,跑马灯,document,函数,代码,getElementByID,菜单,图片,视频教程

Javascript实现相册缩略图导航的两种效果

文章类别:Javascript | 发表日期:2010-5-31 14:28:48

效果如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<meta http-equiv="X-UA-Compatible" content="IE=7" />
<meta name="author" content="rukey67" />
<meta name="description" content="Javascrip实现相册缩略图导航的两种效果,已封装可重用" />
<title>相册导航效果</title>
<style type="text/css">
body {text-align:center;}
* {padding:0; margin:0; border:none;}
ul {list-style:none;}
h1 {margin:12px auto 6px; font-size:32px; color:#91cd02;}
.photoNav01 {margin:24px auto; width:200px; border:1px solid #dddddd; clear:both; overflow:hidden; padding:6px 0 6px 4px; background-color:#f0f0f0;}
.photoNav01 ul {clear:both; overflow:hidden; zoom:1;}
.photoNav01 li {float:left; margin-right:5px; display:inline;}
.photoNav01 li a {display:block;width:53px; height:75px; background-position:center; border:1px solid #ccc;}
.photoNav02 {margin:24px auto; width:256px; border:1px solid #dddddd; clear:both; padding:6px 0;background-color:#f0f0f0;}
.photoNav02 ul {clear:both; zoom:1; padding:0px 1px 0px 6px; overflow:hidden;}
.photoNav02 li {float:left; margin-right:5px; display:inline;}
.photoNav02 li a {display:block;border:1px solid #ccc;width:75px; height:75px; overflow:hidden; text-align:left;}
.photoNav02 li a img {float:left;}
h3{width:600px; margin:0 auto 12px; text-align:left;}
ol {width:600px; margin:0 auto; text-align:left; line-height:20px; font-size:12px; padding-left:48px; color:#666666;}
ol li {margin:0 auto 6px;}
</style>
<script type="text/javascript">
function $(objId){//此函数是document.getElementById方法的简写,根据传递过来的id值获取元素对象,方便操作
 return document.getElementById(objId);
}
/*  --------------以下第一个效果的代码------------------  */
function ImgNav(objId,maxWidth,minWidth,midWidth){//第一个效果的构造函数
 this.containner=$(objId);
 this.imgArr=this.containner.getElementsByTagName("a");
 this.maxWidth=maxWidth;
 this.minWidth=minWidth;
 this.midWidth=midWidth;
 this.initialize(); //启动函数
}
ImgNav.prototype={
 initialize:function(){//Json格式定义原型方法,也可分开写成ImgNav.prototype.initialize=function(){...}
  var classObj=this;//为①处闭包函数引用对象传值
  for(var i=0,l=this.imgArr.length; i<l;i++){
   this.imgArr[i].j=i;//为①处闭包函数引用对象传值,保存i运行时刻的值,方便传给闭包里的函数
   this.imgArr[i].onmouseover=function(e){
    classObj.focusImg(this.j);//① 此处的classObj,this.j 即是之前传值过的变量
   }
   this.imgArr[i].onmouseout=function(event){
    if(this.t!=null){clearTimeout(this.t);}
   }
  }
  this.containner.onmouseout=function(e){ //感谢宝儿兄针对onmouseout事件冒泡的函数:http://bbs.blueidea.com/viewthread.php?tid=2875959
  //以下定义鼠标离开图片队列容器时复位所有图片宽度的函数
   var e=window.event||e,relatedTarget=e.toElement||e.relatedTarget;
   while(relatedTarget&&relatedTarget != this){
    relatedTarget = relatedTarget.parentNode;
   }
   if(!relatedTarget){
    classObj.resetWidth(classObj.imgArr);
   };
  };
 },
 focusImg:function(n){
  for(var i=0,l=this.imgArr.length;i<l;i++){
   if(i==n){//进行循环,如果循环到的序号等于鼠标所在位置的文档对象的索引,则增加该文档对象的宽度
    this.enlarge(this.imgArr[i],this.maxWidth,2);//三个参数,需要操作的文档对象,增大到的最大宽度,增大的步长
   }else{//如果循环到的序号为鼠标所在文档对象之外的对象,则减小其宽度
    this.reduce(this.imgArr[i],this.minWidth,2);//三个参数,需要操作的文档对象,减小到的最小宽度,减小的步长 
   }
  } 
 },
 enlarge:function(obj,w,step){//鼠标划过时增加该对象宽度的函数,接收三个参数:需要操作的文档对象,减到的最小宽度,减小的步长 
  var m1=obj.offsetWidth;
  var m2=w;
  if(m1<m2){//如果对象宽度小于最大宽度,则增加宽度
   if(obj.m!=null){clearInterval(obj.m);}//如果计时器启动,则清除,避免鼠标操作过快时激发多个起计时器,引起冲突
   obj.m=setInterval(function(){//注意此处 obj.m 用法
    m1+=step;
    if(m1>=m2){clearInterval(obj.m);}//如果对象宽度已经增加到超过最大宽度,则停止增加
    obj.style.width=m1+"px";
   },3);
  }
 },
 reduce:function(obj,w,step){//可参见enlarge函数注释,这里的原理差不多
  var m1=obj.offsetWidth;
  var m2=w;
  if(m1>m2){
   if(obj.m!=null){clearInterval(obj.m);}
   obj.m=setInterval(function(){
    m1-=step;
    if(m1<=m2){clearInterval(obj.m);}
    obj.style.width=m1+"px";
   },3);
  }
 },
 resetWidth:function(obj){//当鼠标离开了所有图像时,复位对象宽度到中间值
  for(var i=0,l=obj.length;i<l;i++){
   if(obj[i].offsetWidth<this.midWidth){
    this.enlarge(obj[i],this.midWidth,1);
   }else if(obj[i].offsetWidth>this.midWidth){
    this.reduce(obj[i],this.midWidth,2);
   }
  }
  //alert("冒没冒泡");//调试信息
 }
}
/*  --------------两个效果代码的分隔线------------------  */
/*  --------------以下第二个效果的代码------------------  */
function ImgNav02(objId,width,height){//第二个效果的构造函数
 this.containner=$(objId);
 this.picWidth=width;
 this.picHeight=height;
 this.outerArr=this.containner.getElementsByTagName("a");//获取链接数组,供后面循环进行处理
 this.initialize(); 
}
ImgNav02.prototype={
 initialize:function(){
  var classObj=this;
  for(var i=0,l=this.outerArr.length;i<l;i++){
   this.outerArr[i].onmouseover=function(){//定义鼠标划过事件处理函数,对这个图像增加翻转效果
     classObj.overturn(this);
   }
   this.outerArr[i].onmouseout=function(e){//再次感谢宝儿兄针对onmouseout事件冒泡的函数:http://bbs.blueidea.com/viewthread.php?tid=2875959
    var e=window.event||e,relatedTarget=e.toElement||e.relatedTarget;
    while(relatedTarget&&relatedTarget != this){
     relatedTarget = relatedTarget.parentNode;
    }
    if(!relatedTarget){
     classObj.exchange(this,this.childNodes[1],this.childNodes[0]);//鼠标离开时,再翻转回去,
     //exchange函数接受两个参数,第一个为外面包裹图片的容器,即a对象,第二个为要增大的图片,第三个为要减小的图片
    };
    
   }
  }
 },
 overturn:function(obj){//obj为包含住图片的外面的a容器
  var childImg=obj.childNodes[0];//获取a容器里的图片
  if(!childImg.brotherImg){//如果还没有增加过brother图片,则克隆一个
   childImg.brotherImg=childImg.cloneNode(true);
   childImg.brotherImg.style.width="0px";//设置这个brother图片的各项属性
   childImg.brotherImg.style.height=this.picHeight+"px";//注意此处的高度有必要限定,不然改变宽度是高度也按比例改变
   childImg.style.height=this.picHeight+"px";//注意此处的高度有必要限定,不然改变宽度是高度也按比例改变
   obj.appendChild(childImg.brotherImg);//赋值出一个同样的图片,通过上面属性的设置,这个并排的brother图片不可见
  }
  this.exchange(obj,childImg,childImg.brotherImg);//对原有图片和复制克隆出来的brother图片进行宽度改变,形成翻转效果
 },
 exchange:function(obj,objToReduce,objToEnlarge){
 //exchange函数接受两个参数,第一个为外面包裹图片的容器,即a对象,第二个为要减小的图片,第三个为要增大的图片
  var classObj=this;
  var w1=objToReduce.offsetWidth;
  var w2=objToEnlarge.offsetWidth;
  if(obj.timer!=null){clearInterval(obj.timer);}
  obj.timer=setInterval(function(){
   if(w1<=0||w2>=this.picHeight){
    objToReduce.style.width="0px";
    objToEnlarge.style.width=classObj.picWidth+"px";
    clearInterval(obj.timer);
    return;
   }
   w1-=5;
   w2+=5;
   objToReduce.style.width=w1+"px";
   objToEnlarge.style.width=w2+"px";
  },10)
 }
}
window.onload=function(){
 new ImgNav("smallPic01_1",75,42,53);
 new ImgNav("smallPic01_2",75,42,53);
 new ImgNav02("smallPic02_1",75,75);
 new ImgNav02("smallPic02_2",75,75);
}
</script>
</head>
<body>
<h1>Javascrip实现相册缩略图导航的两种效果</h1>
<div class="photoNav01">
 <ul id="smallPic01_1">
     <li><a href="#" style="background-image:url(http://bbs.blueidea.com/attachment.php?aid=98887&k=44f05243d3bced93dbd3133e2e392e14&t=1220250093&noupdate=yes);"></a></li>
     <li><a href="#" style="background-image:url(http://bbs.blueidea.com/attachment.php?aid=98888&k=1ac6e2e7f0da97da3ecd39577a5cfbb7&t=1220250093&noupdate=yes);"></a></li>
     <li><a href="#" style="background-image:url(http://bbs.blueidea.com/attachment.php?aid=98889&k=8cd1fb1f5f170c241d64d834f049c571&t=1220250093&noupdate=yes);"></a></li>
    </ul>
</div>
<div class="photoNav01">
 <ul id="smallPic01_2">
     <li><a href="#" style="background-image:url(http://bbs.blueidea.com/attachment.php?aid=98890&k=99a6f19ffeab3e22a28108b0e3acd4ca&t=1220250093&noupdate=yes);"></a></li>
     <li><a href="#" style="background-image:url(http://bbs.blueidea.com/attachment.php?aid=98891&k=87cd2f3574a602e0fe4c98d5124ea2c4&t=1220250093&noupdate=yes);"></a></li>
     <li><a href="#" style="background-image:url(http://bbs.blueidea.com/attachment.php?aid=98892&k=6d230901f7c1a2ccc1de5c64340ca2b7&t=1220250093&noupdate=yes);"></a></li>
    </ul>
</div>
<div class="photoNav02">
 <ul id="smallPic02_1">
     <li><a href="#"><img src="http://bbs.blueidea.com/attachment.php?aid=98887&k=44f05243d3bced93dbd3133e2e392e14&t=1220250093&noupdate=yes" /></a></li>
     <li><a href="#"><img src="http://bbs.blueidea.com/attachment.php?aid=98888&k=1ac6e2e7f0da97da3ecd39577a5cfbb7&t=1220250093&noupdate=yes" /></a></li>
     <li><a href="#"><img src="http://bbs.blueidea.com/attachment.php?aid=98891&k=87cd2f3574a602e0fe4c98d5124ea2c4&t=1220250093&noupdate=yes" /></a></li>
    </ul>
</div>
<div class="photoNav02">
 <ul id="smallPic02_2">
     <li><a href="#"><img src="http://bbs.blueidea.com/attachment.php?aid=98892&k=6d230901f7c1a2ccc1de5c64340ca2b7&t=1220250093&noupdate=yes" /></a></li>
     <li><a href="#"><img src="http://bbs.blueidea.com/attachment.php?aid=98893&k=bdb7746fb06d34c778eccd5f4b924fe8&t=1220250093&noupdate=yes" /></a></li>
     <li><a href="#"><img src="http://bbs.blueidea.com/attachment.php?aid=98894&k=9c4463c642f84f829e95209d20548192&t=1220250093&noupdate=yes" /></a></li>
    </ul>
</div>
<h3>几点说明:</h3>
<ol>
    <li>第一个效果是模仿又拍网(yupoo.com)的相册导航实现的,第二个是偶然看到一个摄影网站的头图flash上缩略图的效果</li>
 <li>第一种效果的XHTML结构和CSS样式的设置非常巧妙,对于实现效果有至关重要的作用;</li>
    <li>两段Javascript代码的编写主要运用到,计时器的密切跟踪与及时清除,多个全局计时器变量作为对象的属性与对象绑定方便处理,阻止onmouseout事件“冒泡”的特殊处理方式(行为类似冒泡,经查阅与冒泡并无关系)</li>
    <li>用现成的JS框架可以比较方便的实现这两个效果,但是不经过一步步地手写代码,对于JS的运行机制、代码效率很难有比较深刻的认识,这样即使代码用到了比较完备的框架,也可能是冗繁低效的。</li>
</ol>
</body>
</html>

以上只是两种效果,为了演示重用,故每个效果都分别给出了两个实例,所以有四组图
bbs上的这种演示方式在IE6里会有一些问题,第一个效果鼠标划过时背景不断重载导致不可见
经测试IE6/IE7/IE8/FF2/FF3 都不会有问题
由于第二个效果用了一个IE5不支持的方法,所以效果上会有一些问题,但是不影响可用性


1. 第一个效果是模仿又拍网(yupoo.com)的相册导航实现的,第二个是偶然看到一个摄影网站的头图flash上缩略图的效果,前几天版上有人要过这个效果;
2. 第一种效果的XHTML结构和CSS样式的设置非常巧妙,对于实现效果有至关重要的作用;
3. 两段Javascript代码的编写主要运用到,计时器的密切跟踪与及时清除,多个全局计时器变量作为对象的属性与对象绑定方便处理,阻止onmouseout事件“冒泡”的特殊处理方式(行为类似冒泡,经查阅与冒泡并无关系)
4. 用现成的JS框架可以比较方便的实现这两个效果,但是不经过一步步地手写代码,对于JS的运行机制、代码效率很难有比较深刻的认识,这样即使代码用到了比较完备的框架,也可能是冗繁低效的。

视频教程列表
文章教程搜索
 
Javascript推荐教程
Javascript热门教程
看全部视频教程
购买方式/价格
购买视频教程: 咨询客服
tel:15972130058