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


    关键词: js手风琴 js百叶窗 js百页窗

    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>
    View Code

    实现原理的代码分析

      两个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>
    View Code

    附: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]
      }
    }
        
  • 相关阅读:
    修改ASP.NET MVC Ajax分页组件ASP.NET MvcPager一个小Bug并修该样式为自己所用(一)
    HighCharts报表 API
    自动化开发资料
    修改ASP.NET MVC Ajax分页组件ASP.NET MvcPager一个小Bug并修该样式为自己所用(三)
    网络营销资料收集
    C#扩展方法
    UI Automation Under the Hood (1)
    C#辅助类之ConfigHelper
    设计模式资源汇总
    Windows GUI自动化测试
  • 原文地址:https://www.cnblogs.com/daysme/p/6182900.html
Copyright © 2020-2023  润新知