纯手工打造一款无缝滚动轮播插件

作者 BiYuqi 日期 2017-01-05
纯手工打造一款无缝滚动轮播插件

项目上经常会用到轮播,为避免重复劳动,遂决定实现一个灵活的无缝滚动轮播效果,注意:此插件依赖jquery;直接看代码。本文引入jq版本为1.11;

enter description here

Demo演示

无缝滚动轮播原理

/*
    无缝滚动原理:
        1、前后各加一张图片
        2、每次改变ss-inner盒子的位置(margin-left)
        3、自动轮播
        4、小圆圈点击切换
*/

HTML结构

<div class="ss-wrapper"><!-- 外层盒子 -->
    <div class="ss-inner clearfix"><!-- 内层盒子 -->
        <div class="ss-item"><!-- 图片盒子,数量自定 -->
            <img src="img/banner01.jpg">
        </div>
        <div class="ss-item">
            <img src="img/banner02.jpg">
        </div>
        <div class="ss-item">
            <img src="img/banner03.jpg">
        </div>
        <div class="ss-item">
            <img src="img/banner04.jpg">
        </div>
        <div class="ss-item">
            <img src="img/banner05.jpg">
        </div>
    </div>
    <div class="ss-circle"><!-- 小圆点盒子 -->
        <span class="ss-circle-item active"></span> <!-- 小圆点 数量自定 -->
        <span class="ss-circle-item"></span>
        <span class="ss-circle-item"></span>
        <span class="ss-circle-item"></span>
        <span class="ss-circle-item"></span>
    </div>
    <div class="ss-arrow-left ss-arrow"></div><!-- 左点击 -->
    <div class="ss-arrow-right ss-arrow"></div><!-- 右点击 -->
</div>

说明:html结构必须按照规范,但是图片的数量可以随便增删,小圆点根据图片的数量随意增删

CSS部分

/*这里用*号,清除默认样式,实属偷懒,可自行写reset*/
*{
    margin: 0;
    padding: 0;
}
html,body{
    margin: 0;
    padding: 0;
    width: 100%;
}
.ss-wrapper{
    width: 1000px;
    margin: 0 auto;
    height:564px;
    overflow: hidden;
    position: relative;
}
/*
初始5张 后面会用js计算,不用在意此处
五张默认5000,一张1000,根据自己需要写
*/
.ss-inner{
    width: 5000px;
}
.clearfix{
    display: block;
    content: '';
    overflow: hidden;
    clear: both;
}
.ss-item{
    float: left;
    width: 1000px;
    overflow: hidden;
}
.ss-item img{
    display: block;
    width: 100%;
}
/*小圆圈*/
.ss-circle{
    position: absolute;
    left: 0;
    bottom: 1%;
    width: 100%;
    text-align: center;

}
.ss-circle .ss-circle-item{
    display: inline-block;
    width: 12px;
    height: 12px;
    border-radius: 50%;
    background-color: #fff;
    cursor: pointer;
}
.ss-circle-item.active{
    background-color: #c33;
}
/*左右点击*/
.ss-arrow{
    position: absolute;
    top: 50%;
    margin-top: -40px;
    width: 40px;
    height: 60px;
    cursor: pointer;
    background-color: rgba(0,0,0,.6);
    display: none;
}
.ss-arrow-left{
    left: 2%;
}
.ss-arrow-right{
    right: 2%;
}
.ss-arrow-left:hover{
    background-color: rgba(0,0,0,.4);
}
.ss-arrow-right:hover{
    background-color: rgba(0,0,0,.4);
}

Javascript部分

var module = (function(){
    function Slideshow(obj){
        this.slideShow = obj;//传的形参,当做对象用
        this.wrapperWidth = $('.ss-wrapper');
        this.imgWrapper = $('.ss-inner');
        this.circleItem = $('.ss-circle-item');
        this.arrowBtn = $('.ss-arrow');
        this.arrowBtnLeft = $('.ss-arrow-left');
        this.arrowBtnRight = $('.ss-arrow-right');
        this.imgs = this.imgWrapper.find('.ss-item');//图片所在盒子
        this.index = 1;//
        this.imgWidth = obj.imgWidth || this.imgs.eq(0).width();//设置图片宽度 有默认值
        this.imgHeight = obj.imgHeight || this.imgs.eq(0).height();//设置高度 有默认值
        this.gapTime = obj.time || 3000;//轮播间隔时间
        this.isAutoPlay = obj.isFlag || false;//可选择是否自动轮播
    this.mobileBtn = obj.mobileBtn || false;//移动端是否显示 左右点击按钮
        this.timer = null;//初始化
    }
    Slideshow.prototype = {
    constructor:Slideshow,
        init:function(){
            //拷贝首尾图片
            var firstImg = this.imgs.eq(0).clone();
            var lastImg = this.imgs.eq(this.imgs.length-1).clone();
            //分别插入
            this.imgWrapper.append(firstImg);
            lastImg.insertBefore(this.imgs.eq(0));
            //储存图片个数
            var imgLength = $('.ss-item').length;
            //重新赋予大盒子宽度
            this.imgWrapper.css({
                width:this.imgWidth * imgLength
            });
            //改变盒子的margin-left  显示第一张图片
            this.imgWrapper.css({
                marginLeft: -this.imgWidth
            });
            //自定义宽高
            this.wrapperWidth.css({
                width: this.imgWidth,
                height: this.imgHeight
            });
            //自定义宽高
            $('.ss-item').css({
                width: this.imgWidth,
                height: this.imgHeight
            });
    //是否显示移动端点击按钮
            if(!this.mobileBtn){
                this.arrowBtn.hide();
            }

            //初始化后,下面的事件在此调用
            this.addAutoPlay();
            this.stopAutoPlay();
            this.arrowRightClick();
            this.arrowLeftClick();
            this.circleClick();
        },
    /*自动轮播*/
        addAutoPlay:function(){
            var that = this;
            if(!this.isAutoPlay){
                this.timer = setInterval(function(){
                    that.index++;
                    that.addAnimate();
                },that.gapTime)
            }
        },
        stopAutoPlay:function(){
                var that = this;
        if(!this.mobileBtn){//移动端点击按钮 开关
            this.arrowBtn.hide();
        }else{//
            this.arrowBtn.show();
            this.wrapperWidth.on('mouseenter',function(e){
                that.arrowBtn.fadeIn();//鼠标滑过,显示按钮
                clearInterval(that.timer);
            });
            this.wrapperWidth.on('mouseleave',function(e){
                that.arrowBtn.fadeOut();//鼠标离开,隐藏按钮
                that.addAutoPlay();
            })
        }
        },
        arrowRightClick:function(){
        var that = this;
        //防止点击过快,造成的问题  保存初始时间戳
        var _thistime = Date.now();
        this.arrowBtnRight.on('click',function(){
            //比较两次点击之间的时间,如果点击过快,return
            if((Date.now() - _thistime) < 700){
                return false;
            }else{//符合点击范围,执行动画
                //时间保留到上次点击的地方
                that.index++;
                _thistime = Date.now();
                //运动函数里面 已经处理好index的问题
                that.addAnimate();
            }
        })
        },
        arrowLeftClick:function(){
        var that = this;
        //防止点击过快,造成的问题  保存初始时间戳
        var _thistime = Date.now();
        this.arrowBtnLeft.on('click',function(){
            //比较两次点击之间的时间,如果点击过快,return
            if((Date.now() - _thistime) < 700){
                return false;
            }else{//符合点击范围,执行动画
                //时间保留到上次点击的地方
                that.index--;
                _thistime = Date.now();
                //运动函数里面 已经处理好index的问题
                that.addAnimate();
            }
        })
        },
        circleClick:function(){
        var that = this;
        this.circleItem.each(function(k,v){
            $(v).on('click',function(){
            //点击时当前的next 等于当前的索引k
            that.index = k+1;
            that.addAnimate();
            })
        });
        },
        addAnimate:function(){
            var that = this;
            var boxWrapper = $('.ss-item');//图片容器 用来计算图片数量
            this.imgWrapper.animate({
                marginLeft:-this.imgWidth*that.index
            },700,function(){//轮播一张的动画时间
        //最后一张时
                if(that.index >= boxWrapper.length-1){
                    that.index = 1;
                }
        //第一张往前
                if(that.index <= 0){
                    that.index = boxWrapper.length-2;
                }
        //同时设置相应的位置
                that.imgWrapper.css({
                    marginLeft: -that.imgWidth*that.index
                });

                //小圆圈高亮跟随 处理
                for(var i=0; i<that.circleItem.length; i++){
                    that.circleItem.eq(i).removeClass('active');
                }
                that.circleItem.eq(that.index-1).addClass('active');
            })
        }
    }
    //导出接口
    return {
        Slideshow:Slideshow
    }
})()

使用方法

如何在项目中使用

//根据自己项目,引入正确路径
//引入jquery
<script src="js/jquery.min.js"></script>

//引入轮播插件(轮播起名为slideshow,遂写如下)
<script src="js/slideshow.js"></script>

//引入后就可以直接调用啦.....
<script>
var slideShow = new module.Slideshow({
    time:4000,//轮播时间间隔
    imgWidth:1200,//图片宽度 or 图片所在容器宽度
    imgHeight:450,//图片高度 or 图片所在容器高度
    isFlag:false, //false 为自动轮播
    mobileBtn:true//打开PC端按钮点击 hover事件 false为移动端取消这些功能
})
slideShow.init();
</script>

具体效果请点击文章开头的DEMO演示
说明:

  • time:number 轮播时间间隔(可选 默认3s)
  • imgWidth: number 图片宽度 or 图片所在容器宽度(可选 默认1000),如果想实现全屏轮播,该项目值为$(‘body’).width(); (css里面记得写body{width:100%})
  • imgHeight: number 图片高度 or 图片所在容器高度(可选 有默认值)
  • isFlag:false //false 为自动轮播 ;true 为禁止自动轮播。(可选,默认自动轮播)

结语

本插件还有不太完善之处,如有遇到bug,请与我留言。
后期考虑添加功能

  • 实现样式可定制,包括调整布局
  • 实现多轮播共存
  • 移动端可关闭左右点击按钮,已完成 具体请看demo演示 ,查看源码
  • 增加滑动功能