js手风琴图片切换实现原理及函数分析

实现原理解读

  使用两层for循环实现,
  第一层有三个功能,分别给第个li:
    添加索引
    预设位置
    添加事件
  第二层有两个功能,整理图片位置:
    鼠标的li,以及前面那些li的位置
    鼠标后面那些li的位置

HTML/CSS 解读:略

  HTML/CSS代码:

<!--
Author: XiaoWen
Create a file: 2016-12-14 09:41:11
Last modified: 2016-12-15 12:56:23
Start to work:
Finish the work:
Other information:
-->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>手风琴2</title>
  <style>
    *{
      margin: 0;
      padding: 0;
    }
    body{
      background: #ccc;
    }
    div{
      width: 1100px;
      height: 300px;
      margin: auto;
      background: #ddd;
      margin-top: 40px;
      border-radius:10px;
      border: 10px solid #fff;
      box-shadow:0 0 20px #eee;
    }
    ul,li{
      list-style:none;
    }
    img{
      vertical-align: bottom;
      width: 600px;
      height: 300px;
    }
    ul{
      position: relative;
      overflow: hidden;
      width: 1100px;
      height: 300px;
    }
    ul li{
      position: absolute;
      width: 600px;
      height: 300px;
      overflow: hidden;
    }
  </style>
</head>
<body>
  <div>
    <ul>
      <li><img src="1.jpg" alt="图片1"></li>
      <li><img src="2.jpg" alt="图片2"></li>
      <li><img src="3.jpg" alt="图片3"></li>
      <li><img src="4.jpg" alt="图片4"></li>
      <li><img src="5.jpg" alt="图片5"></li>
      <li><img src="6.jpg" alt="图片6"></li>
    </ul>
  </div>
</body>
</html>

实现原理的代码分析

  两个for循环的js代码:

  无分析的代码:
for(var i=0;i<aLi.length;i++){
  aLi[i].index=i;
  if(i!=0){
    aLi[i].style.left=600+100*(i-1)+‘px‘;
  }
  aLi[i].onmouseover=function(){
    for(var j=0;j<aLi.length;j++){
      if(j<=this.index){
        move(aLi[j],‘left‘,100*j)
      }else{
        move(aLi[j],‘left‘,600+100*(j-1))
      }
    }
  }
}
  有分析的代码:
for(var i=0;i<aLi.length;i++){
  //给每个li添加自定义属性 index ,用来保存i供鼠标函数使用
  aLi[i].index=i;
  //预置图片位置
  if(i!=0){
    //其他图片位置,在第一张图片后面。
    //第一张宽度+后面每张图片显示出来的距离*(后面图片的下标-1)。
    //为什么-1
    //因为第2张图离第1张图0单位距离,第3张离第1张1单位距离……
    aLi[i].style.left=600+100*(i-1)+‘px‘;
  }
  //给每张图片添加鼠标移入事件
  aLi[i].onmouseover=function(){
    for(var j=0;j<aLi.length;j++){

      //若鼠标在第1张图片上时
      //第1次循环, j=0 ;index=0 ;j <= this.index  是;执行 move(aLi[0],‘left‘,100*0) ;第1张图片位置0不动
      //第2次循环, j=1 ;index=0 ;j <= this.index  否;执行 move(aLi[1],‘left‘,600+100*(1-1)) ;第2张图片位置600不动
      //第3次循环, j=2 ;index=0 ;j <= this.index  否;执行 move(aLi[2],‘left‘,600+100*(2-1)) ;第3张图片位置700不动
      //直到循环完成,都不动...

      //若鼠标在第2张图片上时
      //第1次循环, j=0 ;index=1 ;j <= this.index  是;执行 move(aLi[0],‘left‘,100*0) ;第1张图片位置0不动
      //第2次循环, j=1 ;index=1 ;j <= this.index  是;执行 move(aLi[1],‘left‘,100*1) ;第2张图片动,left从600变到100
      //第3次循环, j=2 ;index=1 ;j <= this.index  否;执行 move(aLi[2],‘left‘,600+100*(2-1)) ;第3张图片位置700不动
      //直到循环完成,都不动...

      if(j<=this.index){
        //鼠标所在图片前面那些图片的位置
        move(aLi[j],‘left‘,100*j)
      }else{
        //鼠标所在图片后面那些图片的位置,j-1是为了规律100*0【1-1】,100*1【2-1】...的体现
        //也就是后面的图片距离鼠标所在图片的位置倍数。
        move(aLi[j],‘left‘,600+100*(j-1))
      }
    }
  }
}

单属性运动函数

  无分析的代码:
function move(obj,attr,iTarget){
  clearInterval(obj.timer)
  obj.timer=setInterval(function(){
    var speed=(iTarget-parseInt(getStyle(obj,attr)))/10;
    speed=speed>0 ? Math.ceil(speed) : Math.floor(speed);
    if(iTarget==parseInt(getStyle(obj,attr))){
      clearInterval(obj.timer);
    }else{
      obj.style[attr]=parseInt(getStyle(obj,attr))+speed+‘px‘;
    }
  },10)
}

多属性运动函数

  有分析的代码:
function startMove(obj,json,fnEnd){
  //每次调用时,需要只有一个定时器在工作,在开始运动时关闭所有定时器
  //并且关闭或开启都是当前物体的定时器,防止与页面上其他定时器冲突,使每个定时器互不干扰
  clearInterval(obj.timer);
  obj.timer=setInterval(function(){
    var bStop=true; //假设所有值都已经到达目标值
    for(var name in json){
      var iTarget=json[name]; //所有的目标值
      if(name == ‘opacity‘){ // opacity 比较特殊,值是0到1之间
        var cur=parseInt(parseFloat(getStyle(obj,name))*100); //转小数为整数,让下面的代码容易计算
      }else{
        var cur=parseInt(getStyle(obj,name)); //cur是物体当前数值
      }
      var speed=(iTarget-cur)/10; //整体的速度,数字越小运动越慢
      speed=speed>0?Math.ceil(speed):Math.floor(speed);
      if(name==‘opacity‘){
        obj.style.opacity=(cur+speed)/100;
      }else{
        obj.style[name]=cur+speed+‘px‘; //除了opacity之外其他都需要px
      };
      //当某个值没有到目标值时
      if(cur!=iTarget){
        bStop=false;
      };
    };
    if(bStop){
      clearInterval(obj.timer);
      //当前运动结束后的操作,也就是第三个参数
      if(fnEnd){ //如果有这个参数,就执行
        fnEnd();
      }
    }
  },20)
}

完整效果代码

<!--
Author: XiaoWen
Create a file: 2016-12-14 09:41:11
Last modified: 2016-12-15 13:23:08
Start to work:
Finish the work:
Other information:
-->
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>手风琴2</title>
  <style>
    *{
      margin: 0;
      padding: 0;
    }
    body{
      background: #ccc;
    }
    div{
      width: 1100px;
      height: 300px;
      margin: auto;
      background: #ddd;
      margin-top: 40px;
      border-radius:10px;
      border: 10px solid #fff;
      box-shadow:0 0 20px #eee;
    }
    ul,li{
      list-style:none;
    }
    img{
      vertical-align: bottom;
      width: 600px;
      height: 300px;
    }
    ul{
      position: relative;
      overflow: hidden;
      width: 1100px;
      height: 300px;
    }
    ul li{
      position: absolute;
      width: 600px;
      height: 300px;
      overflow: hidden;
    }
  </style>
</head>
<body>
  <div>
    <ul>
      <li><img src="1.jpg" alt="图片1"></li>
      <li><img src="2.jpg" alt="图片2"></li>
      <li><img src="3.jpg" alt="图片3"></li>
      <li><img src="4.jpg" alt="图片4"></li>
      <li><img src="5.jpg" alt="图片5"></li>
      <li><img src="6.jpg" alt="图片6"></li>
    </ul>
  </div>
  <script>
  var aLi=document.getElementsByTagName(‘li‘);
  for(var i=0;i<aLi.length;i++){
    //给每个li添加自定义属性 index ,用来保存i供鼠标函数使用
    aLi[i].index=i;
    //预置图片位置
    if(i!=0){
      //其他图片位置,在第一张图片后面。
      //第一张宽度+后面每张图片显示出来的距离*(后面图片的下标-1)。
      //为什么-1
      //因为第2张图离第1张图0单位距离,第3张离第1张1单位距离……
      aLi[i].style.left=600+100*(i-1)+‘px‘;
    }
    //给每张图片添加鼠标移入事件
    aLi[i].onmouseover=function(){
      for(var j=0;j<aLi.length;j++){

        //若鼠标在第1张图片上时
        //第1次循环, j=0 ;index=0 ;j <= this.index  是;执行 move(aLi[0],‘left‘,100*0) ;第1张图片位置0不动
        //第2次循环, j=1 ;index=0 ;j <= this.index  否;执行 move(aLi[1],‘left‘,600+100*(1-1)) ;第2张图片位置600不动
        //第3次循环, j=2 ;index=0 ;j <= this.index  否;执行 move(aLi[2],‘left‘,600+100*(2-1)) ;第3张图片位置700不动
        //直到循环完成,都不动...

        //若鼠标在第2张图片上时
        //第1次循环, j=0 ;index=1 ;j <= this.index  是;执行 move(aLi[0],‘left‘,100*0) ;第1张图片位置0不动
        //第2次循环, j=1 ;index=1 ;j <= this.index  是;执行 move(aLi[1],‘left‘,100*1) ;第2张图片动,left从600变到100
        //第3次循环, j=2 ;index=1 ;j <= this.index  否;执行 move(aLi[2],‘left‘,600+100*(2-1)) ;第3张图片位置700不动
        //直到循环完成,都不动...

        if(j<=this.index){
          //鼠标所在图片前面那些图片的位置
          move(aLi[j],‘left‘,100*j)
        }else{
          //鼠标所在图片后面那些图片的位置,j-1是为了规律100*0【1-1】,100*1【2-1】...的体现
          //也就是后面的图片距离鼠标所在图片的位置倍数。
          move(aLi[j],‘left‘,600+100*(j-1))
        }
      }
    }
  }
  function getStyle(obj,attr){
    if(obj.currentStyle){
      return obj.currentStyle[attr]
    }else{
      return getComputedStyle(obj)[attr]
    }
  }
  function move(obj,attr,iTarget){
    clearInterval(obj.timer)
    obj.timer=setInterval(function(){
      var speed=(iTarget-parseInt(getStyle(obj,attr)))/10;
      speed=speed>0 ? Math.ceil(speed) : Math.floor(speed);
      if(iTarget==parseInt(getStyle(obj,attr))){
        clearInterval(obj.timer);
      }else{
        obj.style[attr]=parseInt(getStyle(obj,attr))+speed+‘px‘;
      }
    },10)
  }
  function startMove(obj,json,fnEnd){
    //每次调用时,需要只有一个定时器在工作,在开始运动时关闭所有定时器
    //并且关闭或开启都是当前物体的定时器,防止与页面上其他定时器冲突,使每个定时器互不干扰
    clearInterval(obj.timer);
    obj.timer=setInterval(function(){
      var bStop=true; //假设所有值都已经到达目标值
      for(var name in json){
        var iTarget=json[name]; //所有的目标值
        if(name == ‘opacity‘){ // opacity 比较特殊,值是0到1之间
          var cur=parseInt(parseFloat(getStyle(obj,name))*100); //转小数为整数,让下面的代码容易计算
        }else{
          var cur=parseInt(getStyle(obj,name)); //cur是物体当前数值
        }
        var speed=(iTarget-cur)/10; //整体的速度,数字越小运动越慢
        speed=speed>0?Math.ceil(speed):Math.floor(speed);
        if(name==‘opacity‘){
          obj.style.opacity=(cur+speed)/100;
        }else{
          obj.style[name]=cur+speed+‘px‘; //除了opacity之外其他都需要px
        };
        //当某个值没有到目标值时
        if(cur!=iTarget){
          bStop=false;
        };
      };
      if(bStop){
        clearInterval(obj.timer);
        //当前运动结束后的操作,也就是第三个参数
        if(fnEnd){ //如果有这个参数,就执行
          fnEnd();
        }
      }
    },20)
  }
  </script>
</body>
</html>

附:CSS值获取函数

  关于JS获取CSS值的研究请移步:  《JS获取元素CSS值的各种方法分析》  http://www.cnblogs.com/daysme/p/6117174.html
function getStyle(obj,attr){
  if(obj.currentStyle){
    return obj.currentStyle[attr]
  }else{
    return getComputedStyle(obj)[attr]
  }
}
    
时间: 2024-08-06 15:59:32

js手风琴图片切换实现原理及函数分析的相关文章

原生JS编写图片切换效果和点击按钮的样式变化

这两天更进一步的了解了JS,老师让我们用原生的js编写图片切换和改变点击按钮样式,就是让我们学会怎么去把一个问题拆分,怎么将一个大问题拆分成许多的小问题,再用函数封装起来.比如一个点击按钮,让其点击时背景色发生改变,点击另一个时,上一个按钮要变回原来本有的颜色:这个问题用jquery,一行代码就搞定,但是用原生js就得分三个部分来考虑: 1.添加改变背景的样式. 2.怎么获取到除了当前点击的按钮以外其他的兄弟节点. 3.怎么去除按钮的样式属性. 也讲了事件委托,实现了可以删除新添加的元素的功能.

js实现图片切换效果

用js实现点击按钮,图片切换的效果: 1 <div class="box" id="box"> 2 <div class="img_box" id="img_box"> 3 <img src="../raw/b1.jpg" class="image" > 4 <img src="../raw/b2.jpg" class=&qu

js基础图片切换

<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content=

js 插入图片切换,innerHTML

<!DOCTYPE HTML><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>无标题文档</title><style>p { margin:0; }body { text-align:center; }#box { width:400px; height:400

JS美女图片切换带视觉差

使用JS实现,多张图片动态切换查看效果:http://hovertree.com/texiao/js/21/ 效果图: 转自:http://hovertree.com/h/bjaf/iamhxcyk.htm 参考:hovertree.com/code/jquery/yaar4u7l.htm http://hovertree.com/hvtart/bjae/f03e85410878db53.htm 更多特效:http://www.cnblogs.com/roucheng/p/texiao.html

js简单图片切换

1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"/> 5 6 <title> 7 8 </title> 9 10 </head> 11 <style> 12 #zp img{ 13 margin:0 auto; 14 } 15 </style> 16 <body> 17 <div id=&qu

JS函数传参实例应用:多组图片切换实例

之前的博客有一个图片切换的例子,实现了简单轮播图的点击切换的案例,今天就说一下多组轮播切换,前提是布局差不多,通过函数传参的形式减少代码应用,但是同时还能实现效果.先来看一下之前那个例子的实现图片: 那么今天我来实现两组这样的图片切换,通过传参数来实现,这样分可以减少js代码: <div class="box" id="pic1"> <img src="" /> <span>数量正在加载中--</span

atitit.GUI图片非规则按钮跟动态图片切换的实现模式总结java .net c# c++ web html js

atitit.GUI图片非规则按钮跟动态图片切换的实现模式总结java .net c# c++ web html js 1. 图片按钮的效果总结 1 1.1. 按钮图片自动缩放的. 1 1.2. 不要边框,如果用自定义图片做按钮背景可以设为 false. 2 1.3. 异形按钮 2 1.4. 不绘制焦点 2 1.5. 鼠标经过时的图标 2 1.6. 选中时的图标 2 1.7. 禁用时显示的图标 2 1.8. 可能需要按钮半透明效果 2 2. 图片按钮的实现 2 2.1. 优先模式:button控

jquery.cycle.js图片切换插件参数详解

jquery.cycle.js是jquery的一个插件,主要用来实现千奇百怪的图片切换效果---当然,不是图片也能切换,只是它经常被用来做图片切换而已:这个插件总共有27种效果,是非常好的插件,用到手机版开发是很好的插件来的: 当然jquery.cycle.js的强大远不止于此,下面列举一些它的基本参数: fx:'fade'>值:字符串,作用:选择特效.切换效果是它的重头戏,我统计过,jquery.cycle.js支持27种切换效果,我一一进行了测试,列举在jquery.cycle.js切换特效