轮播图组件

组件api说明

   1、依赖move.js,组件前一定要引入move.js

   2、轮播图需要有一个父级,这个父级一定要给一个id

 

默认参数:

this.settings={

id:'pic', //轮播图父级的id, 必需传的参数

autoplay:true, //自动播放,   true为自动,false为不自动,默认为true

intervalTime:1000, //间隔时间, 运动后停顿的时间,默认1s

loop:true, //循环播放, true为循环,false为不循环,默认为true

totalNum:5, //图片总量

moveNum:1, //单次运动的图片数量 (图片总量必须为运动数量的整倍数)

circle:true, //小圆点功能, true为显示,false为不显示,默认显示

moveWay:'opacity' //运动方式, opacity为透明度过渡,position为位置过渡

};

 

有了组件,可以更方便,引入组件后,只需要用户参入相应参数,就可以实现轮播图功能

下面是banner轮播图的代码:

//banner轮播图
var bannerPic=new Carousel();
bannerPic.init({
    id:'bannerPic',                
    autoplay:true,            
    intervalTime:3000,        
    loop:true,                
    totalNum:5,                
    moveNum:1,                
    circle:true,                
    moveWay:'opacity'    
});
;(function(window,undefined){
    
    var Carousel=function(){
        //配置参数
        this.settings={
            id:'pic',                //轮播图父级的id, 必需传的参数
            autoplay:true,            //自动播放,          true为自动,false为不自动,默认为true
            intervalTime:1000,        //间隔时间,            运动后停顿的时间,默认1s
            loop:true,                //循环播放,            true为循环,false为不循环,默认为true
            totalNum:5,                //图片总量
            moveNum:1,                //单次运动的图片数量    (图片总量必须为运动数量的整倍数)
            circle:true,                //小圆点功能,    true为显示,false为不显示,默认显示
            moveWay:'opacity'        //运动方式,        opacity为透明度过渡,position为位置过渡
        };
    };
    
    Carousel.prototype={
        constructor:Carousel,//重新指向构造函数
        init:function(opt){
            var opt=opt||this.settings;//用户没有传参,就使用默认的
            
            for (var attr in opt) {
                this.settings[attr]=opt[attr];//用户参数覆盖默认参数
            }
            
            this.createDom();//调用函数
            
            
        },
        createDom:function(){//创建dom结构
            var This=this;
            this.box=document.getElementById(this.settings.id);
            //创建上一个按钮
            this.prevBtn=document.createElement("div");
            this.prevBtn.className='prev';
            this.prevBtn.innerHTML='<';
            this.prevBtn.onclick=function(){
                This.prev();
                This.trigger('leftClick');
            };
            this.box.appendChild(this.prevBtn);//把创建的元素添加到父级box身上
            
            //创建下一个按钮
            this.nextBtn=document.createElement("div");
            this.nextBtn.className='next';
            this.nextBtn.innerHTML='>';
            this.nextBtn.onclick=function(){
                This.next();
                This.trigger('rightClick');
                
                
            };
            this.box.appendChild(this.nextBtn);//把创建的元素添加到父级box身上
            
            
            //创建圆点的父级
            this.circleWrap=document.createElement("div");
            this.circleWrap.className='circle';
            //创建圆点
            this.circles=[];//存圆点,方便后面修改圆点的class
            for (var i=0;i<this.settings.totalNum/this.settings.moveNum;i++) {
                var span=document.createElement("span");
                span.index=i;
                span.onclick=function(){
                    This.cn=this.index;
                    This[This.settings.moveWay+'Fn']();
                    
                };
                
                this.circleWrap.appendChild(span);//添加圆点给父级
                this.circles.push(span);
            }
            
            this.circles[0].className='active';
            if(this.settings.circle){//如果需要圆点,才添加
                this.box.appendChild(this.circleWrap);//添加圆点父级到box身上
            }
            this.moveInit();
        },
        
        //运动函数初始化
        moveInit:function(){
            this.cn=0;//当前索引
            this.ln=0;//上一个索引
            this.canClick=true;//是否可以再次点击
            this.endNum=this.settings.totalNum/this.settings.moveNum;    //非循环运动时,运动的停止条件
            this.opacityItem=this.box.children[0].children;        //需要运动透明度的元素,图片
            this.positionItemWrap=this.box.children[0].children[0];    //需要运动位置元素的父级
            this.positionItem=this.positionItemWrap.children;    //需要运动位置的所有元素li
            
            switch(this.settings.moveWay){
                case 'opacity'://运动透明度,需要设置透明度与transition
                    for(var i=0;i<this.opacityItem.length;i++){
                        this.opacityItem[i].style.opacity=0;
                        this.opacityItem[i].style.transition='.3s opacity';
                    }
                    this.opacityItem[0].style.opacity=1;
                    break;
                case 'position'://运动位置,需要设置父级的宽度
                    //注意一个元素的宽度一定要加上margin
                    var leftMargin=parseInt(getComputedStyle(this.positionItem[0]).marginLeft);
                    var rightMargin=parseInt(getComputedStyle(this.positionItem[0]).marginRight);
                    //一个运动元素的实际宽度 
                    this.singleWidth=leftMargin+this.positionItem[0].offsetWidth+rightMargin;//找问题,要炸了offsetWidth没加
                    
                    //如果内容需要循环,要复制一份内容
                    if(this.settings.loop){
                        this.positionItemWrap.innerHTML+=this.positionItemWrap.innerHTML;//找问题,要炸了innerHTML没加
                    }
                    //复制内容后才能计算宽度
                    this.positionItemWrap.style.width=this.singleWidth*this.positionItem.length+'px';
                    
                    break;
            
            }
            if(this.settings.autoplay){
                this.autoPlay();//this不能忘记!!!!
            }
            
        },
        
        
        //透明度运动方式
        opacityFn:function(){//选项卡原理
            //左边到头,this.cn<0
            if(this.cn<0){
                if(this.settings.loop){
                    //循环播放
                    this.cn=this.endNum-1;
                }else{
                    //非循环播放
                    this.cn=0;
                    this.canClick=true;//最后一张,或者第一张点击了,即使再次点击transitionend不会执行
                    
                }

            }
            //右边到头
            if(this.cn>this.endNum-1){
                if(this.settings.loop){
                    //循环播放
                    this.cn=0;
                }else{
                    //非循环播放
                    this.cn=this.endNum-1;
                    this.canClick=true;
                }
            }
            
            //清除上一个圆点和图片的初始样式
            this.opacityItem[this.ln].style.opacity=0;
            this.circles[this.ln].className='';
            //当前
            this.opacityItem[this.cn].style.opacity=1;
            this.circles[this.cn].className='active';
            
            var en=0;
            var This=this;
            this.opacityItem[this.cn].addEventListener('transitionend',function(){
                en++;
                if(en==1){
                    This.canClick=true;
                    This.ln=This.cn;
                    
                    This.endFn();//运动完成触发的自定义事件
                    
                }
            });
        },
        
        
        //位置运动方式
        positionFn:function(){
            //左边到头,this.cn<0
            if(this.cn<0){
                if(this.settings.loop){
                    //循环播放
                    /*
                     * 在这里需要做两件事情
                     *     1、先让运动的父级的位置到中间(复制后的图片),为了往右走不会出现空白
                     *     2、同时需要修改索引值(到了中间了,并不是停在那了,而是要运动出前一排,所以cn的值要减个1,为了就是能运动)
                     */
                    this.positionItemWrap.style.left=-this.positionItemWrap.offsetWidth/2+'px';
                    this.cn=this.endNum-1;
                }else{
                    //非循环播放
                    this.cn=0;
                }

            }
            //右边到头
            /*if(this.cn>this.endNum-1){
                if(this.settings.loop){
                    //循环播放,这里不用做改变,需要在运动结束后做条件判断
                    
                }else{
                    //非循环播放
                    this.cn=this.endNum-1;
                }
            }*/
            if(this.cn>this.endNum-1 && !this.settings.loop){
                    this.cn=this.endNum-1;
                
            }
            
            //当不循环播放的时候,没有圆点,需要修改圆点
            if(!this.settings.loop){
                //清除上一个圆点和图片的初始样式
                this.circles[this.ln].className='';
                //当前
                this.circles[this.cn].className='active';
            }
            
            //运动
            //left=一个元素的宽度*当前cn的值*一次运动的个数
            var This=this;
            move(this.positionItemWrap,{left:-this.cn*this.singleWidth*this.settings.moveNum},300,'linear',function(){
                //当运动到复制后的图片时,让父级的left值变为0
                if(This.cn==This.endNum){
                    this.style.left=0;
                    This.cn=0;
                }
                
                This.endFn();//运动完成触发的自定义事件
                
                This.canClick=true;
                This.ln=This.cn;
            });
        },
        
        //上一个按钮点击功能
        prev:function(){
            if(!this.canClick){//图片运动的时候,不能点击按钮
                return;
            }
            this.canClick=false;
            this.cn--;
            this[this.settings.moveWay+'Fn']();
            
        },
        
        //下一个按钮点击功能
        next:function(){
            if(!this.canClick){//图片运动的时候,不能点击按钮
                return;
            }
            this.canClick=false;
            this.cn++;
            this[this.settings.moveWay+'Fn']();
        },
        
        
        //自动播放功能
        autoPlay:function(){
            var This=this;
            this.timer=setInterval(function(){
                This.next();
            },this.settings.intervalTime);
            
            //鼠标移入停止运动
            this.box.onmouseenter=function(){
                clearInterval(This.timer);
                This.timer=null;
            }
            //鼠标移出继续运动
            this.box.onmouseleave=function(){
                This.autoPlay();
            }
            
            
            
            
        },
        
        
        //添加自定义事件
        on:function(type,listener){
            this.events=this.events||{};//若用户第一次没有添加自定义事件为{},第二次添加的时候就是this.events
            this.events[type]=this.events[type]||[];
            this.events[type].push(listener);
            
        },
        
        //调用自定义事件触发器
        trigger:function(type){//自定义事件触发器
            //不是所有组件都有自定义事件,故需要判断
            
            if(this.events&&this.events[type]){
                for (var i=0;i<this.events[type].length;i++) {
                    this.events[type][i].call(this);
                }
                
            }
        },
        
        //运动完成后触发的自定义事件
        endFn:function(){
            //非循环的运动,才添加自定义事件
            if(!this.settings.loop){
                //左边到头
                if(this.cn==0){
                    this.trigger('leftEnd');
                }
                //右边到头
                if(this.cn==this.endNum-1){
                    this.trigger('rightEnd');
                }
            }
        }
        
    };
    
    window.Carousel=Carousel;//把Carousel挂载到window上
})(window,undefined);
原文地址:https://www.cnblogs.com/shengnan-2017/p/carousel-recommend.html