前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >移动端轮播图效果实现

移动端轮播图效果实现

作者头像
切图仔
发布2022-09-08 16:15:25
1.6K0
发布2022-09-08 16:15:25
举报
文章被收录于专栏:生如夏花绚烂生如夏花绚烂

基本结构

代码语言: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 此时实现回弹操作

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

到此轮播图制作完成。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-08-04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档