移动端轮播图(自动循环轮播、无缝衔接、短距离回弹、图片可拖动、拖动结束播放)

本案例轮播的图片为4个

第四张 第一张 第二章 第三张 第四张 第一张
index从1开始,通过index来使得装图片的容器,left=-(index-1)*屏幕宽度+'px'

通过定时器开启轮播


1、自动循环轮播和无缝衔接:
	(1)在四个图片前添四个图片的最后一张,四个图片的尾添加图片的第一张
		使得轮播时,最后一张图片能自然切换到第一张
	
	(2)无缝衔接(当原最后一张图片轮播到原首张时从首战开始轮播)
		当原最后一张图片轮播到原首张时,关掉过渡动画,位移到原首张的距离

2、短距离回弹
	判断拉动距离,如果距离小于给定值,不改变当前图片index

3、图片可拖动
	通过touch事件,根据坐标进行

4、拖动结束播放
	监听过渡态结束事件,在事件中开启轮播,注意清除之前的定时器

5、监听当索引(照片)处于最后一张(index=5)和出于第一张(index=0),关闭过渡态,直接位移到原图片对应位置
	使用webkitTransitionEnd事件,当过渡态结束时触发,监听index变化

6、当处于过渡时不可拖动(节流阀)
	在过渡态结束监听事件中设置旗帜=true,当处于过渡态时,设置旗帜=true
	拖动事件和松开事件,只有当过渡态结束时才触发

代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin:0;
            padding: 0;
        }
        .con{
            width:100%;
            height: 300px;
            overflow: hidden;
            position: relative;
        }
        .banner{
            width:100%;
            height: 300px;
            left: 0;
            display: flex;
            position: absolute;
        }
        .img{
            width: 100%;
            height: 100%;
        }
        .dot{
            width: 100%;
            position: absolute;
            margin: 0 auto;
            display: flex;
            justify-content: center;
            bottom: 20px;

        }
        .dot>div{
            height: 10px;
            width: 10px;
            border-radius: 10px;
            margin: 0 10px;
            background-color: #ccc;
        }
        .dot>.on{
            background-color: white;
        }
    </style>
</head>
<body>

    <div class='con'>
        <div class='banner'>
            
        </div>
        <div class='dot'>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </div>
    </div>


    <script>
      var banner=document.querySelector('.banner');
      var dots=document.querySelectorAll('.dot>div')
      banner.style.left=-banner.offsetWidth+'px';

      let timer;

      let fx; //第一次触发x坐标
      let mx; //移动过程x坐标
      let ex; //结束过程x坐标
      let left;

      //索引从1开始,0为最后一张图片索引
      let index=1;

      //在过渡态结束才能手动滑动
      let transition=true;

      
      //制造图片
      function getImg(url){
        let index=url;
        url='./imgs/'+url+'.jpg'
        let img=document.createElement('img');
        img.className='img';
        img.src=url;
        img.style.borderRadius='20px';

        return img;
      }

      //图片只有4张
      for(let i=1;i<5;i++)
      {
          banner.appendChild(getImg(i));
      }

      //给首前添加最后一张图片,尾后添加首张图片
      banner.insertBefore(getImg(4),document.querySelector('.img:first-of-type'));
      banner.appendChild(getImg(1));
      
      //添加当前圆点样式
      function now(index)
      {
        dots.forEach((item)=>{
            item.className='';
        })
        dots[index].className='on';
      }

      now(0);

    //自动轮播
      var startTimer=function()
      {
            if(timer)
            {
                clearInterval(timer);
            }
            timer=setInterval(()=>{
            //要移动4次才能到末尾添加的图片,然后返回到首张,即index=5
            index++;
            banner.style.transition='1s linear';
            banner.style.left=-(index)*banner.offsetWidth+'px';
            transition=false;


        },2000)
      }

      startTimer();

      

      //手动轮播 
      //记录第一次触摸位置
      banner.ontouchstart=function(e)
      { 
          //按下关闭轮播
          clearInterval(timer);
          let touch=e.touches[0];
          fx=touch.clientX;
          left=banner.style.left.substring(0,banner.style.left.length-2);
       
      }

      //记录移动过程距离
      banner.ontouchmove=function(e)
      {
        if(transition)
        {
            let touch=event.touches[0];

            mx=touch.clientX;

            move=fx-mx;

            //最终拖动位移
            let res=left-move;
            //取消拉动的过渡动画,否则会出现延迟响应
            banner.style.transition='none';
            banner.style.left=res+'px';
        }
        
      }

      //记录最后一次位置,并根据第一次位置判断方向
      banner.ontouchend=function(e)
      {
        if(transition)
        {
            transition=false;
            let touch=e.changedTouches[0];

            ex=touch.clientX;
            let indicator=fx-ex;
            //判断方向
            //判断拉取距离,小于某个值,只是回弹,即index不变
            if(Math.abs(indicator)>100)
            {
                //超过距离进行翻页
                if(indicator<0) //上一张
                {
                    index--;

                }else{  //下一张
                    
                    index++;
                }
            }

            //翻页
            banner.style.transition='1s linear';
            banner.style.left=-(index)*banner.offsetWidth+'px';

        }


      }

      //监听过渡态结束,每当到首尾最后一张时,滑动到对应位置衔接,以及对应圆点显示
      banner.addEventListener('webkitTransitionEnd',()=>{
        //如果到第一张index=0,就回到最后一张-1,即index=4
        transition=true;
        if(index==0)
        {
            index=4;
            //清除过渡
            banner.style.transition='none';
            banner.style.left=-index*banner.offsetWidth+'px';
            
        }

        //如果到最后一张,即index=5,回到第一张,index=1

        if(index==5)
        {
            index=1;
            //清除过渡
            banner.style.transition='none';
            banner.style.left=-index*banner.offsetWidth+'px';
        }
        now(index-1);
        startTimer();

      })




    </script>
</body>

</html>
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值