移动端轮播图

1. 页面布局

1.1 页面框架

<body>
    <div class="box">
        <div class="tupian">
            <img src="4.webp" alt="">
            <img src="1.webp" alt="">
            <img src="2.webp" alt="">
            <img src="3.webp" alt="">
            <img src="4.webp" alt="">
            <img src="1.webp" alt="">
        </div>
        <ul>
            <li data-aa="0" class="aaa"></li>
            <li data-aa="1"></li>
            <li data-aa="2"></li>
            <li data-aa="3"></li>
        </ul>
    </div>
</body>

1.2css样式

    <style>
        *{
            margin: 0;
            padding: 0;
        }
        .box {
            position: relative;
            /* 在移动端如果不设置下面样式 可以拖动 */
            overflow: hidden;
        }

        .tupian img {
            float: left;
            width: 16.66%;
        }

        .tupian {
            width: 600%;
            margin-left:-393px;
        }

        ul {
            position: absolute;
            top: 300px;
            right: 20px;
        }

        ul li {
            float: left;
            margin-left: 30px;
            background-color: #fff;
            display: block;
            width: 20px;
            height: 10px;
        }

        .aaa {
            background-color: coral;
        }
    </style>

2. 实现自动轮播

2.1 获取用到元素

    var box = document.querySelector('.box')
    var tupian = document.querySelector('.tupian')
    var ul = document.querySelector('ul')

2.2 通过css3的 transition 和 transform 属性实现动画效果

  • 创建全局变量num作为轮播图的计数器
  • 创建全局变量imgWidth 此变量就是整个box的宽度
  • 创建一个定时器 时隔3秒触发一次 num++ 同时执行下面代码:
    var translate = -num * imgWidth 整体tupian向左每次移动一张图片宽度
  • 通过transition实现过渡效果
var timer = setInterval(function () {
        num++
        var translate = -num * imgWidth
        //设置元素的移动在2s内完成 给元素添加过度
        tupian.style.transition = 'all 1s'
        tupian.style.transform = 'TranslateX(' + translate + 'px)'
    }, 3000)

以上代码计时器开启后会不断切换宽度 当num>4后没有图片显示 当num<0后前方也没有图片

2.3 解决上面问题 实现重复轮播图片

  • 通过给 tupian 添加 transitionend 事件 (当transition过渡效果完成后触发此事件)
  • 在此事件中通过判断num==4时 将tupian.style.transform的值设为0 也就是回到第一张位置
  • 同时将取消过度效果
  • 此事件中添加判断
    当num==4时也就是最后一张图片
    当num<0时也就是第一张图片(后补那张和最后一张相同)
//过度执行结束后 会触发 transitionend 事件
    tupian.addEventListener('transitionend', function () {
        // console.log(num)
        if (num == 4) {
            num = 0
            //取消过度
            tupian.style.transition = 'none'
            tupian.style.transform = 'TranslateX(0px)'
        }else if(num<0){
            num=3
            var translatex=-num*imgWidth
            tupian.style.transition = 'none'
            tupian.style.transform = 'TranslateX('+translatex+'px)'
        }

3. 手指拖动实现轮播

1. 手指触摸到元素上 停止轮播图自动播放
2. 判断手指的移动方向 然后图片向这个方向移动
3. 判断手指的移动距离 如果超出范围就切换轮播图 如果没有超出这个范围 则继续显示原来的轮播图

3.1 设置全局变量

//获取手指的初始坐标
var startx = 0
//获取图片的初始坐标
var tupianx = 0
//手指的移动距离
var movex = 0

3.2 为 tupian 添加手指按下事件

事件中:

  • 停止轮播图
  • 获取手指按下时的坐标 赋值给变量 startx
  • 获取按下手指时的tupian坐标
tupian.addEventListener('touchstart', function (e) {
        //手指按下时将现在坐标赋值给 startx
        startx = e.targetTouches[0].pageX
        tupianx = tupian.offsetLeft
        //清除定时器
        clearInterval(timer)
        timer = null
    })

3.3 为 tupian 添加手指在DOM上的移动事件

事件中:

  • 通过e.targetTouchrs[0].pageX不断获取手指的坐标
  • 通过公式movex=e.targetTouchrs[0].pageX - startx 拿到手指的移动距离
  • 将上面的这个距离赋值给 tupian 让其随之移动
  • 判断flag是后面的节流阀代码 当过渡效果未完成不允许拖动
//为tupian添加 touchmove(手指拖动) 事件 拖动 tupian
    tupian.addEventListener('touchmove', function (e) {
        //禁止默认行为
        e.preventDefault()
        if (flag) {
            movex = e.targetTouches[0].pageX - startx
            var translatex = -num * imgWidth + movex
            //取消过度
            tupian.style.transition = 'none'
            this.style.transform = 'Translatex(' + translatex + 'px)'
        }

    })

3.4 为 tupian 添加手指离开DOM事件

事件中:

  • 判断手指的移动有没有超过50
    超过50切换轮播图
    未超50回弹轮播图
  • 同时判断手指滑动方向 决定切换上一张还是下一张轮播图
  • 并且重启轮播图
tupian.addEventListener('touchend', function () {
        /*
        根据手指的移动距离 判断是否需要切换轮播图
        如果移动距离 >=50 切换轮播图
        如果移动距离  <50 回弹轮播图
        */
        //设置节流阀
        if (flag) {
            //将节流阀设置为false
            flag = false
            if (Math.abs(movex) >= 50) {
                if (movex > 0) {
                    num--
                } else {
                    num++
                }
                var translatex = -num * imgWidth
                //添加过度效果
                tupian.style.transition = 'all 1s'
                this.style.transform = 'Translatex(' + translatex + 'px)'
            } else {
                var translatex = -num * imgWidth
                //添加过度效果
                tupian.style.transition = 'all 1s'
                this.style.transform = 'Translatex(' + translatex + 'px)'
            }
            //清除定时器
            clearInterval(timer)
            //重启轮播
            timer = setInterval(function () {
                num++
                var translate = -num * imgWidth
                //设置元素的移动在2s内完成 给元素添加过度
                tupian.style.transition = 'all 1s'
                tupian.style.transform = 'TranslateX(' + translate + 'px)'
            }, 3000)
        }
    })

4. 设置指示器的样式

效果:当轮播图转换到相应的图片是 下面相应的指示器与其他颜色不同

  • 设置全局变量sort用来为指示器计数
  • 把sort变量放置到transitionend事件中 也就是过度效果完成后sort=图片的下标值
  • 设置指示器效果函数如下两种:

第一种:将每次调用此函数 将所有的li标签的类名清空
同时为显示图片对应的指示器添加类名 函数调用在transitionend事件中

//设置指示器的样式
    function yuan() {
        for (var i = 0; i < ul.children.length; i++) {
            ul.children[i].className = ''
        }
        //设置对应指示器的样式
        ul.children[sort].className = 'aaa'
    }

第二种:通过classlist属性 找出具有aaa类名的li将其类名清空 同时为显示图片对应的指示器添加类名
函数调用在transitionend事件中

//设置指示器的样式
    function yuan() {
        ul.querySelector('.aaa').classList.remove('aaa')
        //设置对应指示器的样式
        ul.children[sort].className = 'aaa'
    }

完整代码:

<!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;
        }
        .box {
            position: relative;
            /* 在移动端如果不设置下面样式 可以拖动 */
            overflow: hidden;
        }

        .tupian img {
            float: left;
            width: 16.66%;
        }

        .tupian {
            width: 600%;
            margin-left:-414px;
        }

        ul {
            position: absolute;
            top: 300px;
            right: 20px;
        }

        ul li {
            float: left;
            margin-left: 30px;
            background-color: #fff;
            display: block;
            width: 20px;
            height: 10px;
        }

        .aaa {
            background-color: coral;
        }
    </style>
</head>

<body>
    <div class="box">
        <div class="tupian">
            <img src="4.webp" alt="">
            <img src="1.webp" alt="">
            <img src="2.webp" alt="">
            <img src="3.webp" alt="">
            <img src="4.webp" alt="">
            <img src="1.webp" alt="">
        </div>
        <ul>
            <li data-aa="0" class="aaa"></li>
            <li data-aa="1"></li>
            <li data-aa="2"></li>
            <li data-aa="3"></li>
        </ul>
    </div>
</body>
<script>
    var box = document.querySelector('.box')
    var tupian = document.querySelector('.tupian')
    var ul = document.querySelector('ul')
    //获取移动的宽度
    var imgWidth = box.offsetWidth
    //创建变量 用于轮播图的计数器
    var num = 0
    //创建一个用于指示器的计数器
    var sort = 0
    //设置节流阀
    flag = true
    //创建指示器的计数器
    var sort=0

    //自动轮播效果的实现
    var timer = setInterval(function () {
        num++
        var translate = -num * imgWidth
        //设置元素的移动在2s内完成 给元素添加过度
        tupian.style.transition = 'all 1s'
        tupian.style.transform = 'TranslateX(' + translate + 'px)'
    }, 3000)
    //过度执行结束后 会触发 transitionend 事件
    tupian.addEventListener('transitionend', function () {
        // console.log(num)
        if (num == 4) {
            num = 0
            //取消过度
            tupian.style.transition = 'none'
            tupian.style.transform = 'TranslateX(0px)'
        }else if(num<0){
            num=3
            var translatex=-num*imgWidth
            tupian.style.transition = 'none'
            tupian.style.transform = 'TranslateX('+translatex+'px)'
        }
        //为节流阀设置为true
        flag = true

        //设置指示器样式
        sort=num
        yuan()
    })

    /*
    实现手指拖动轮播图
    (1手指触摸到元素上 停止轮播图自动播放
    (2判断手指的移动方向 然后图片向这个方向移动
    (3判断手指的移动距离 如果超出范围就切换轮播图 如果没有超出这个范围 则继续显示原来的轮播图
    */
    //获取手指的初始坐标
    var startx = 0
    //获取图片的初始坐标
    var tupianx = 0
    //手指的移动距离
    var movex = 0

    //为tupian添加 touchstart(手指触摸) 事件 停止轮播
    tupian.addEventListener('touchstart', function (e) {
        //手指按下时将现在坐标赋值给 startx
        startx = e.targetTouches[0].pageX
        tupianx = tupian.offsetLeft
        //清除定时器
        clearInterval(timer)
        timer = null
    })

    //为tupian添加 touchmove(手指拖动) 事件 拖动 tupian
    tupian.addEventListener('touchmove', function (e) {
        //禁止默认行为
        e.preventDefault()
        if (flag) {
            movex = e.targetTouches[0].pageX - startx
            var translatex = -num * imgWidth + movex
            //取消过度
            tupian.style.transition = 'none'
            this.style.transform = 'Translatex(' + translatex + 'px)'
        }

    })

    //为tupian添加 touchend(手指离开) 事件 重启轮播
    tupian.addEventListener('touchend', function () {
        /*
        根据手指的移动距离 判断是否需要切换轮播图
        如果移动距离 >=50 切换轮播图
        如果移动距离  <50 回弹轮播图
        */
        //设置节流阀
        if (flag) {
            //将节流阀设置为false
            flag = false
            if (Math.abs(movex) >= 50) {
                if (movex > 0) {
                    num--
                } else {
                    num++
                }
                var translatex = -num * imgWidth
                //添加过度效果
                tupian.style.transition = 'all 1s'
                this.style.transform = 'Translatex(' + translatex + 'px)'
            } else {
                var translatex = -num * imgWidth
                //添加过度效果
                tupian.style.transition = 'all 1s'
                this.style.transform = 'Translatex(' + translatex + 'px)'
            }
            //清除定时器
            clearInterval(timer)
            //重启轮播
            timer = setInterval(function () {
                num++
                var translate = -num * imgWidth
                //设置元素的移动在2s内完成 给元素添加过度
                tupian.style.transition = 'all 1s'
                tupian.style.transform = 'TranslateX(' + translate + 'px)'
            }, 3000)
        }
    })




    //设置指示器的样式
    function yuan() {
        for (var i = 0; i < ul.children.length; i++) {
            ul.children[i].className = ''
        }
        //设置对应指示器的样式
        ul.children[sort].className = 'aaa'
    }
</script>

</html>
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
移动端轮播图可以使用原生JS和CSS3来实现。下面提供一个例子[^1],帮助你完成移动端轮播图: 1. HTML结构 ```html <div class="container"> <div class="img-box"> <img src="1.jpg" alt=""> <img src="2.jpg" alt=""> <img src="3.jpg" alt=""> <img src="4.jpg" alt=""> </div> <div class="dot-box"> <span></span> <span></span> <span></span> <span></span> </div> </div> ``` 2. CSS样式 ```css .container { width: 100%; overflow: hidden; position: relative; } .img-box { display: flex; width: 400%; transition: all .5s; } .img-box img { width: 25%; } .dot-box { position: absolute; bottom: 20px; left: 50%; transform: translateX(-50%); } .dot-box span { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin: 0 5px; background-color: #fff; opacity: .5; cursor: pointer; } .dot-box span.active { opacity: 1; } ``` 3. JavaScript代码 ```javascript var container = document.querySelector('.container'); var imgBox = document.querySelector('.img-box'); var dots = document.querySelectorAll('.dot-box span'); var index = 0; var timer = null; var startX = 0; var startY = 0; var moveX = 0; var moveY = 0; var distanceX = 0; var distanceY = 0; // 自动轮播 timer = setInterval(function() { index++; if (index > 3) { index = 0; } changeImage(); }, 2000); // 触摸事件 container.addEventListener('touchstart', function(e) { clearInterval(timer); startX = e.touches.clientX; startY = e.touches.clientY; }); container.addEventListener('touchmove', function(e) { moveX = e.touches.clientX; moveY = e.touches.clientY; distanceX = moveX - startX; distanceY = moveY - startY; imgBox.style.transform = 'translateX(' + (-index * 100 - distanceX) / 4 + '%)'; }); container.addEventListener('touchend', function(e) { if (Math.abs(distanceX) > 50) { if (distanceX > 0) { index--; if (index < 0) { index = 3; } } else { index++; if (index > 3) { index = 0; } } } changeImage(); timer = setInterval(function() { index++; if (index > 3) { index = 0; } changeImage(); }, 2000); }); // 点击事件 dots.forEach(function(dot, i) { dot.addEventListener('click', function() { index = i; changeImage(); }); }); // 切换图片和小圆点的样式 function changeImage() { imgBox.style.transform = 'translateX(' + (-index * 100) + '%)'; dots.forEach(function(dot) { dot.classList.remove('active'); }); dots[index].classList.add('active'); } ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

几何心凉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值