移动端轮播图效果实现

2022-09-08 16:15:25 浏览数 (2)

基本结构

代码语言:javascript复制
<div class="focus">
        <ul>
            <!-- 最前面为最后一张 -->
            <li><img src="./images/three.jpg" alt=""></li>

            <li><img src="./images/one.jpg" alt=""></li>
            <li><img src="./images/two.jpg" alt=""></li>
            <li><img src="./images/three.jpg" alt=""></li>
            <!-- 最后一张==第一张 -->
            <li><img src="./images/one.jpg" alt=""></li>

        </ul>
        <ol>
            <li class="current"></li>
            <li></li>
            <li></li>
        </ol>
    </div>

基本css

代码语言:javascript复制
/* 轮播图 */
.focus{
  position: relative;
  padding-top: 44px;
  overflow:hidden;//溢出的图片隐藏
}
.focus ul{
  width: 500%;
  overflow:hidden;/*清除浮动*/
    margin-left:-100%;/*默认展示第一张图片而不是克隆的最后一张图片*/
}
.focus ul li{
  width: 20% ;/*防止图片变大5倍*/
  float:left;
}
.focus img{
  width: 100%;
  height:1.333333rem  
}
/*园点*/
.focus ol {
  position: absolute;
  bottom: 5px;
  right: 5px;
}
.focus ol li{
  width: 5px;
  height: 5px;
  background-color: #fff;
  display:inline-block;
  border-radius: 5px;

}
/*当前高亮*/
.focus ol li.current{
  width: 15px;
}

为了使ul装下5张图片我们将其宽度设置为500%,但这样会造成图片放大5倍,因此我们为img的父元素li设置20%的宽度占ul的五分之一,这时候图片就显示正常了

自动播放

利用索引号与宽度实现每次要滚动的距离 每次移动的距离等于当前索引*宽度 js代码

代码语言:javascript复制
window.addEventListener('load',function(){
   //1. 获取元素
   var focus = document.querySelector('.focus'); 
   var ul = focus.children[0];
   //2.获取focus的宽度
   var w = focus.offsetWidth;
   //3.定时器开启
   var index = 0;
   var timer = setInterval(function(){
    index  
    //移动距离
    var translateX = -index*w
    ul.style.transition = 'all .3s'
    ul.style.transform = 'translate(' translateX 'px)'
   },2000);

})

到此实现自动轮播效果,接下来需要实现无缝滚动

无缝滚动

原理很简单,当滚动到最后一张图片(克隆的第一张图片)的时候,我们快速跳到第一张图片的位置继续滚动即可

不过需要注意的是我们使用了过渡效果,如果我们直接跳转会有过渡效果这样用户会很明显的感觉到,我们要做的是用户察觉不出来图片已经跳到了第一张

解决办法是等过渡完成后在进行判断当前索引是不是最后一个,如果是则跳转到第一张图片 通过 过渡完成事件transitionend 代码实现

代码语言:javascript复制
...
//过渡完成后判断是否到最后一张图片
   ul.addEventListener('transitionend',function(){
    //    无缝滚动实现
       if(index>=3){
           index=0
           ul.style.transition = 'none'/*跳转去掉过渡效果 */
           /*按照最新的索引移动位置 也就是快速定位到真正的第一张图片*/
           /*在从第一张图片的位置继续轮播 */
           var translateX = -index*w
           ul.style.transform = 'translateX(' translateX 'px)'
       }
   })

})
此时无缝滚动完成一半了

我们还有一种情况,当用户在第一张图片向右边拖到图片时,此时应该看到最后一张,并且由最后一张继续轮播,我们可以先写一部分逻辑和上面类似

代码语言:javascript复制
...
 ul.addEventListener('transitionend',function(){
    //    无缝滚动实现
       if(index>=3){
           index=0
           ul.style.transition = 'none'/*跳转去掉过渡效果 */
           /*按照最新的索引移动位置 也就是快速定位到真正的第一张图片*/
           /*在从第一张图片的位置继续轮播 */
           var translateX = -index*w
           ul.style.transform = 'translateX(' translateX 'px)'
       }else if(index < 0){
           index=2/*即将跳转到克隆的第一张图片 */
           ul.style.transition = 'none'/*跳转去掉过渡效果 */
           var translateX = -index*w
           ul.style.transform = 'translateX(' translateX 'px)'
       }
   })

})

当用户在第一张进行向右拖动时,用户看到的是克隆版的最后一张,为了实现无缝滚动效果,此时我们瞬间跳转到真正的最后一张也就是索引为2的,当执行定时器时,索引变成了3,此时又会跳到第一张,由此实现了无缝滚动。

小圆点高亮实现

这里我们要用到一个新的属性---classList classList属性是HTML5新添加的一个属性,可以返回元素的类名,不过ie10以上才支持 但是我们是做移动端所以不用考虑ie的问题。 该属性还可用于在元素添加,移除,切换 CSS类,有如下方法

  1. element.classList.add('类名') 追加类名(不用加点)
  2. element.classList.remove(’类名‘) 移除类名
  3. element.classList.toggle('类名') 切换类名(原来有这个类名则取消否则添加)

代码如下

代码语言:javascript复制
...
 // 小圆点跟随变化
    //将ol里面的li带有current的类名元素选择出来去掉类名
    ol.querySelector('li.current').classList.remove('current')
    //当前索引li高亮
    ol.children[index].classList.add('current')
   })

})

手动拖放元素

接下来我们实现手指拖放元素,通过手指控制图片位置,要用到两个移动端的事件

touchstart:获取手指初始坐标 touchmove:移动手指 计算手指滑动距离,并且移动盒子 代码如下

代码语言:javascript复制
    ...
     //当前索引li高亮
    ol.children[index].classList.add('current')
   })
   //手指滑动轮播
   //触摸元素获取手指初始坐标
   
   var startX = 0;
   var moveX = 0;
   ul.addEventListener('touchstart',function(e){
       /*第一个手指的坐标*/
    startX =  e.targetTouches[0].pageX;
        /*手指按下清除定时器*/
    clearInterval(timer)
   })
   ul.addEventListener('touchmove',function(e){
    /*移动的时候计算移动距离*/
    /* 移动之后的手指坐标减去 初始坐标就是手指移动的距离  */     
    moveX = e.targetTouches[0].pageX-startX
    //移动盒子 :盒子原来的位置加上手指移动的距离
    var translateX = -index*w  moveX;
    ul.style.transform = 'translateX(' translateX 'px)' 
})

})

实现轮播图上一张、下一张、回弹

上面代码只实现了拖放元素,并没有实现轮播图上一张、下一张、回弹的功能,我们要根据用户滑动的距离来实现上一张下一张或者回弹的功能

touchend 手指离开时 根据滑动距离分不同的情况

代码如下

代码语言:javascript复制
 //触摸元素获取手指初始坐标
   
   var startX = 0;
   var moveX = 0;
   var flag = false;//用户是否产生滑动标识
   ul.addEventListener('touchstart',function(e){
       /*第一个手指的坐标*/
    startX =  e.targetTouches[0].pageX;
    /*手指按下清除定时器*/
    clearInterval(timer)
   })
   ul.addEventListener('touchmove',function(e){
    /*移动的时候计算移动距离*/
    /* 移动之后的手指坐标减去 初始坐标就是手指移动的距离  */     
    moveX = e.targetTouches[0].pageX-startX
    //移动盒子 :盒子原来的位置加上手指移动的距离
    var translateX = -index*w  moveX;
    ul.style.transition='none';
    ul.style.transform = 'translateX(' translateX 'px)';
    flag=true;//移动时状态为正
    e.preventDefault();//阻止滚动屏幕的行为
});
//手指离开时 回弹,上一张。下一张
ul.addEventListener('touchend',function(e){
    // 如果用户确实发生了移动操作
    console.log(moveX)
    if(flag){
        if(Math.abs(moveX)>50){
            //上一张 (右滑 moveX为正)
            if(moveX>0){
                index--;
            }else if(moveX<0){
                //下一张 (左滑 moveX为负)
                index  ;
            }
            var translateX = -index*w;
            ul.style.transition='all .3s';
            ul.style.transform = 'translateX(' translateX 'px)'; 
            
        }else{
            //小于50像素回弹 回到当前位置不变
            var translateX = -index*w;
            ul.style.transition='all .1s';
            ul.style.transform = 'translateX(' translateX 'px)'; 
        }
        moveX=0;//手指离开时清除移动距离防止用户移动离开后在次点击触发
    }
    //手指离开重新开启定时器
    clearInterval(timer);
    timer = setInterval(function(){
        index  
        //移动距离
        var translateX = -index*w
        ul.style.transition = 'all .2s'
        ul.style.transform = 'translateX(' translateX 'px)'
    
        console.log(index)
    
    },2000);
})

})

1.我们添加了用户滑动标识,当滑动时才时这个标识生效,避免用户点击的时候触发轮播 2.在用户手指离开时我们先进行判断用户是否产生了滑动操作,如果产生了滑动操作则根据用户行为实现上一张、下一张、回弹效果 分为下面几种情况 2.1用户滑动距离取绝对值>50 此时进行上一张下一张操作 2.1.1:当滑动距离>0时 代表右滑,此时实现上一张 2.1.2:当滑动距离<0时 代表左滑,此时实现下一张

2.2用户滑动距离取绝对值<50 此时实现回弹操作

并且在手指离开时我们清除了原来的滑动距离;重新开启了定时器

到此轮播图制作完成。

1 人点赞