原生JS的滚动轮播插件(简单实用版)

直接上代码先看效果,不依赖任何库,需要的直接复制这个swiper类就可以了,结构可以继续嵌套,样式可以自行修改!

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <title>滚动轮播插件</title>
</head>
<style>
    html,body{
        padding: 0;
        margin: 0;
        width: 100%;
    }
    li{
        list-style:none;
    }
    div,ul,li{
        box-sizing: border-box;
        margin: 0;
        padding: 0;
    }
    .scroll{
        padding: 20px;
        height: 140px;
    }
    .swiper{
        overflow: hidden;
        width: 100%;
        height: 100%;
        /*padding: 10px;*/
        position: relative;
    }
    .swiperUl{
        height: 100%;
    }
    .leftBtn,.rightBtn{
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
    }
    .leftBtn{
        left: 10px;
    }
    .rightBtn{
        right: 10px;
    }
    .swiperUl li{
        float: left;
        width: 120px;
        height: 120px;
        background-color: skyblue;
    }
</style>
<body>
    <!--Dom结构-->
    <div class="scroll">
        <div class='swiper' id='swiper'>
            <ul class='swiperUl'>
                <li>1</li>
                <li>2</li>
                <li>3</li>
                <li>4</li>
                <li>5</li>
                <li>6</li>
                <li>7</li>
                <li>8</li>
                <li>9</li>
            </ul>
            <div class='leftBtn'><</div>
             <!--左右箭头可以自己放置icon或者图片,不需要左右箭头的直接注释,当然,左右轮播就不会生效了-->
            <div class='rightBtn'>></div>
        </div>
    </div>
</body>
<script>
    class Swiper{//li只能设置padding
        constructor(result){//result是使用插件时传导过来的参数
            this.element = result.element;//容器元素
            this.step = result.step;
            this.distance = result.distance;
            this.number = result.number;
            this.ul = null;
            this.list = null;//所有的li
            this.liWidth = 0;//li的长度
            this.scrollMax = 0;
            this.startX = 0;
            this.moveX = 0;
            this.offsetX = 0;
            this.swiperNow = 0;//ul的位置(初始是0,后面累加)
            this.alginOffset = 0;//
            this.leftBtn = null;//左箭头
            this.rightBtn = null;//右箭头
            this.init();
        }
        init(){//初始方法
            let that = this;
            let swiper = document.getElementById(this.element);
            let swiperWidth = swiper.clientWidth;
            this.ul = swiper.children[0];
            this.list = this.ul.children;
            if(this.number){//number存在就有插件动态设置宽度,否则就是使用者自己设置
                this.liWidth = swiperWidth/this.number;
                for(let i=0;i<this.list.length;i++){
                    this.list[i].style.width = this.liWidth + "px"
                }
            }else{
                this.liWidth = this.list[0].clientWidth;//li的长度
            }
            this.ul.style.width = this.liWidth*this.list.length + 'px';///设置Ul的长度
            this.scrollMax = this.ul.clientWidth - swiperWidth;//最大能滑动的距离
            // 监听事件
            swiper.addEventListener('touchstart', function (e) {
                this.startX =e.targetTouches[0].clientX;
            }.bind(that))
            swiper.addEventListener('touchmove', function (e) {
                this.moveX = e.targetTouches[0].clientX;//现在滚动到的距离
                //手指的偏移量:
                if(this.alginOffset){//是否是每次的初始滑动
                    this.offsetX = this.moveX - this.alginOffset;//实际滑动的距离=现在的点-上一次的点
                }else{
                    this.offsetX = this.moveX - this.startX
                }
                this.alginOffset = this.moveX;//上一次滑动到的点的位置
                if(this.scrollMax<=0){//如果当前ul总长还不超过外面显示的盒子,那么就不能滑动
                    return
                }
                if(this.offsetX < 0){
                    //手指右滑
                    this.swiperNow+=(this.offsetX*1.5);//控制滑动的倍数
                    if(Math.abs(this.swiperNow)>this.scrollMax){
                        this.swiperNow = -this.scrollMax
                    }
                    this.ul.style.transform = "translateX(" + this.swiperNow + "px)";
                }else if(this.offsetX > 0){
                    //手指左滑
                    this.swiperNow+=(this.offsetX*1.5);//控制滑动的倍数
                    if(this.swiperNow>0){
                        this.swiperNow = 0;
                    }
                    this.ul.style.transform = "translateX(" + this.swiperNow + "px)";
                }
            }.bind(that))
            swiper.addEventListener('touchend', function (e) {
                //结束滑动,要清除之前记录的上一次滚动距离
                this.alginOffset = 0;
            }.bind(that))
            if(swiper.children[1]){
                this.leftBtn = swiper.children[1];
                this.leftBtn.addEventListener('click',this.leftBtnClick.bind(that));
            }
            if(swiper.children[2]){
                this.rightBtn = swiper.children[2];
                this.rightBtn.addEventListener('click',this.rightBtnClick.bind(that));
            }
        }
        leftBtnClick(){
            if(this.scrollMax<=0){
                return;
            }
            let startPos = this.swiperNow;
            //做一个处理:必须要让轮播滚动为li的整倍数(就会显示3个Li)
            this.swiperNow = (Math.floor(this.swiperNow/this.liWidth)+this.step)*this.liWidth;//计算当前是第几个Li,然后移动3个
            if(this.swiperNow>0){
                this.swiperNow = 0;
            }
            this.animate.call(this,this.ul,startPos,this.swiperNow);
        }
        rightBtnClick(){
            if(this.scrollMax<=0){
                return;
            }
            let starPos = this.swiperNow;
            this.swiperNow = (Math.ceil(this.swiperNow/this.liWidth)-this.step)*this.liWidth;//计算当前是第几个Li,然后移动3个
            if(Math.abs(this.swiperNow)>this.scrollMax){
                this.swiperNow = -this.scrollMax
            }
            this.animate.call(this,this.ul,starPos,this.swiperNow);
        }
        animate(element,swiperNow, target) {
            //元素,元素当前位置,需要去的目标位置
            //这个元素只能有一个定时器
            let distance = this.distance;
            clearInterval(element.timerId);
            //给这个元素设置定时器
            element.timerId = setInterval(function () {
                //步进值
                let step =distance;
                // swiperNow;//当前位置
                //若当前位置的距离大于目标位置的距离 step应该是-10
                if (swiperNow > target) {//0,-350
                    step = -step;
                }
                swiperNow += step;
                //停止
                if (Math.abs(swiperNow - target) <= Math.abs(step)) {
                    swiperNow = target;
                    clearInterval(element.timerId);
                    element.style.transform = "translateX(" + swiperNow + "px)";
                    return;
                }
                element.style.transform = "translateX(" + swiperNow + "px)";
            }, 16)
        }
    }
</script>
<script>
    new Swiper({
        element:'swiper',//容器
        step:1,//一次滚动几个li
        distance:20,//每16毫秒滚动的像素(每帧滚动像素值)
        number:3,//一页几个li,如果需要自己设置大小,可以不传或者传个0
    })
</script>
</html>

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值