移动端与PC端企业级轮播图制作(使用了节流操作,不怕狂点)

写一个轮播图大概分为以下几步:
(0.获取索引小圆点)
1.制作辅助图(前后各复制一个图片,将最后一张放在最前面(appendChild(节点)),将第一张插入到最后面使用insertBefore(节点,位置))
2.开启一个定时器(setInterval)
3.定时器里面有个方法是设置正确的位置(setRightPosition)
4.设置正确的位置方法里面包含1.设置位置(setPosition) 2.检查位置(checkPosition) 两个方法
5.给小圆点添加颜色可以放在检查位置的后面,等检查完位置也就是校正索引后设置小圆点颜色

移动端可以添加手指的touchstart,touchmove,touchend三个方法
其中在touchstart中停止定时器,判断当前是否正在滑动,如果是就return,如果不是就获取手指刚接触的位置也就是起始位置
touchmove中获取手指滑动当前X轴的位置currentX = e.touches[0].pageX 获取起始位置与当前位置的距离 this.distance = currentX - this.startX 获取起始位置时候的距离 也就是设置位置时的位置let startPosition = -this.currentIndex * this.sliderWidth 用起始位置加上移动距离 再设置位置 let currentPosition = startPosition + this.distance this.setPosition(currentPosition)即可达到一个页面随手指滑动的效果
touchend
中, 获取手指滑动距离的绝对值 let currentMove = Math.abs(this.distance);
因为设置位置时都是根据索引设置的,所以我们要改变的只是索引的位置,然后设置正确的位置最后开启定时器即可
if (currentMove == 0) return
else if ((this.distance > 0) && (currentMove > (this.sliderWidth * 0.25))) {
this.currentIndex–
} else if ((this.distance < 0) && (currentMove > (this.sliderWidth * 0.25))) {
this.currentIndex++
}
this.setRightPosition(-this.currentIndex * this.sliderWidth)
this.startTimeout()

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>轮播图制作</title>
    <link rel="stylesheet" href="./index.css">
</head>

<body>
    <div class="swiper">
        <ul class="clearfix">
            <li><img src="./images/1.jpg" alt=""></li>
            <li><img src="./images/2.jpg" alt=""></li>
            <li><img src="./images/3.jpg" alt=""></li>
            <li><img src="./images/4.jpg" alt=""></li>
            <li><img src="./images/5.jpg" alt=""></li>
        </ul>
        <div class="left-box">
            <span>&lt;</span>
        </div>
        <div class="right-box">
            <span>&gt;</span>
        </div>
        <div class="index-box">
            <ol></ol>
        </div>
    </div>




    <script src="./index.js"></script>
    <script>
        const slider = new Slider(".swiper")
    </script>

</body>

</html>

class Slider {
    constructor(cls) {
        // 拿到父盒子容器也就是视口大小
        this.box = document.querySelector(cls)
            // ul标签也是图片的直接父盒子
        this.picBox = this.box.querySelector("ul")
            // 索引盒子
        this.indexBox = this.box.querySelector(".index-box")
            // 左侧箭头
        this.leftBox = this.box.querySelector(".left-box")
            // 右侧箭头
        this.rightBox = this.box.querySelector(".right-box")
            // 图片的张数
        this.picNum = this.picBox.children.length
            // 当前索引,默认为1
        this.currentIndex = 1
            // 视口宽度
        this.sliderWidth = this.box.offsetWidth
            // 轮播延时
        this.delay = 3000
            // transition延时
        this.animateTime = 300
            // 定时器句柄
        this.timer = null
            // 当前是否在滑动
        this.scrolling = false
        this.init()
    }
    init() {
        this.pointInit()
        this.eventInit()
        this.copyPic()
        this.startTimeout()
    }
    next() {
        this.endTimeout()
        this.currentIndex++
            this.setRightPosition(-this.currentIndex * this.sliderWidth)
        this.startTimeout()
    }
    previous() {
        this.endTimeout()
        this.currentIndex--
            this.setRightPosition(-this.currentIndex * this.sliderWidth)
        this.startTimeout()
    }
    touchStart(e) {
        if (this.scrolling) return
            // 关闭定时器
        this.endTimeout()
            // 获取触摸起始位置
        this.startX = e.touches[0].pageX;


    }
    touchMove(e) {
        // 当前触摸的x轴位置
        let currentX = e.touches[0].pageX
            // 触摸一共移动x轴距离
        this.distance = currentX - this.startX
            // 获取触摸起始位置
        let startPosition = -this.currentIndex * this.sliderWidth
        // 当前拖拽触摸的位置
        let currentPosition = startPosition + this.distance
        // 实时变化
        this.setPosition(currentPosition)
    }
    touchEnd() {
            // 1.获取移动的距离
            let currentMove = Math.abs(this.distance);
            if (currentMove == 0) return
            else if ((this.distance > 0) && (currentMove > (this.sliderWidth * 0.25))) {
                this.currentIndex--
            } else if ((this.distance < 0) && (currentMove > (this.sliderWidth * 0.25))) {
                this.currentIndex++
            }
            // 设置正确的位置
            this.setRightPosition(-this.currentIndex * this.sliderWidth)
            // 开启定时器
            this.startTimeout()
        }
        // 节流函数
    throttle(fun) {
            let time = 0
            let that = this
            return function() {
                let now = Date.now()
                if ((now - time) > 500) {
                    fun.call(that)
                    time = now
                }
            }
        }
        // 闭包执行函数
    eventInit() {
        const next = this.throttle(this.next)
        const previous = this.throttle(this.previous)
        this.leftBox.addEventListener("click", () => {
            previous()
        })
        this.rightBox.addEventListener("click", () => {
            next()
        })
        this.picBox.addEventListener("touchstart", (e) => {
            this.touchStart(e)
        })
        this.picBox.addEventListener("touchmove", (e) => {
            this.touchMove(e)
        })
        this.picBox.addEventListener("touchend", (e) => {
            this.touchEnd(e)
        })

    }
    startTimeout() {
        this.timer = setInterval(() => {
            this.currentIndex++;
            this.setRightPosition(-this.currentIndex * this.sliderWidth)
        }, this.delay);
    }
    endTimeout() {
        clearInterval(this.timer)
    }
    setPointColor() {
        let num = this.indexBox.children[0].children.length
        for (let i = 0; i < num; i++) {
            this.indexBox.children[0].children[i].classList.remove("active")
        }
        this.indexBox.children[0].children[this.currentIndex - 1].classList.add("active")
    }
    pointInit() {
            // 自动创建小圆点
            for (let i = 0; i < this.picNum; i++) {
                let li = document.createElement("li")
                this.indexBox.children[0].appendChild(li)
            }
            this.indexBox.children[0].children[0].classList.add("active")
            this.indexBox.children[0].style.width = this.indexBox.children[0].children.length * 10 * 2 + "px"
            Array.prototype.forEach.call(this.indexBox.children[0].children, (item, index) => {
                item.addEventListener("click", () => {
                    if (this.scrolling == true) return
                    else {
                        this.currentIndex = index + 1
                        this.setPosition(-this.currentIndex * this.sliderWidth)
                        this.checkPosition()
                    }
                })
                item.addEventListener("mouseleave", () => {
                    this.startTimeout()
                })
                item.addEventListener("mouseenter", () => {
                    this.endTimeout()
                })
            })
        }
        //复制图片,形成辅助图
    copyPic() {
            if (this.picNum > 1) {
                let firstPic = this.picBox.children[0].cloneNode(true)
                let lastPic = this.picBox.children[this.picNum - 1].cloneNode(true)
                this.picBox.appendChild(firstPic)
                this.picBox.insertBefore(lastPic, this.picBox.children[0])
            }
            this.picBox.style.width = (this.sliderWidth * this.picBox.children.length) + "px"
            this.setPosition(-this.sliderWidth)
        }
        //设置正确的位置,主要逻辑是先设置位置然后判断位置是否正确
    setRightPosition(position) {
            // 是否正在滚动
            this.scrolling = true
            this.picBox.style.transition = `left ${this.animateTime}ms`
                // 设置位置
            this.setPosition(position)
                // 检查当前位置是否正确
            this.checkPosition()
                // 结束正在滚动
            this.scrolling = false
        }
        //设置图片位置
    setPosition(offset) {
            this.picBox.style.left = `${offset}px`
        }
        //检查当前的位置设置是否正确
    checkPosition() {

        setTimeout(() => {
            // 清除偷梁换柱动画的300ms过渡,否则会看出跳转
            this.picBox.style.transition = "0ms"
            if (this.currentIndex == 0) {
                this.currentIndex = this.picNum
                this.setPosition(-this.currentIndex * this.sliderWidth)
            }
            if (this.currentIndex == this.picNum + 1) {
                this.currentIndex = 1
                this.setPosition(-this.currentIndex * this.sliderWidth)
            }
            //设置小圆点颜色
            this.setPointColor()
        }, this.animateTime);
        //必须要加上定时器,否则直接执行将300ms延时覆盖掉,这里的延时必须设置为与动画时长相同的
        // 因为当动画执行完之后才进行偷梁换柱,否则动画不会执行,就直接偷梁换柱了
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值