原生js面向對象實現移動端輪播圖


在前端頁面開發過程中,頁面中的輪播圖特效很常見,因此我就想封裝一個自己的原生JS的輪播圖組件。之前自己寫pc端的比較多,也沒有用面向對象的方式來寫,沒寫過移動端,因為要考慮很多,最近花了三天才完成了移動端輪播,都快寫瘋了。

主要的功能有:自動輪播,點擊某一張圖片對應的小圓點就跳轉到指定圖片,還可以自定義每張圖輪播的延時,不過延時參數不是必須的參數,可以不指定延時,使用默認延時。

/**
 * Created by shentao on 2018/2/10.
 */
(function(){
    //定義一個公共函數,方便獲取dom元素
    function $_(name){
        return document.querySelectorAll(name);
    }
    var mslider=function(option){
        //設置默認參數
        this.defaultopt={
            slideCell:".wrap",
            mainCell:".box",
            interTime:1000,
            autoPlay:false//自動播放
        }
        //判斷傳入的opts是否有默認參數中的值,如果默認參數值不存在opts中
        //就把默認參數加進opts中,這樣就不會把默認參數修改了
        option=option||this.defaultopt;
        for(var k in this.defaultopt){
            if(!option[k]){
                option[k]=this.defaultopt[k];
            }
        }
        this.option=option;
        this.timer=null;//定義一個定時器變量
        this.wrap=$_(this.option.slideCell)[0];//最外層容易,顯示當前的圖片
        this.box=$_(this.option.mainCell)[0];//輪播圖片的包裹層
        this.ali=$_(this.option.mainCell+" li");//輪播圖片集合
        this.len=this.ali.length;//輪播圖片的數目
        this.aliWidth=parseInt(getComputedStyle(this.wrap).width);//每個圖片的寬度
        this.aliHeight=parseInt(getComputedStyle(this.ali[0]).height);//每個圖片的告訴
        this.iNow=0;//當前顯示第幾張圖片
        this.int();//執行初始化函數
    }
    mslider.prototype={
        constructor:mslider,
        int:function(){
            var _this=this;
            this.createNode();
            this.addEvent();
            if(this.option.autoPlay==true){
                this.timer=setInterval(_this.auto_play(),this.option.interTime)
            }
            this.create_page();//自動分頁
        },
        //包裹曾頭部尾部增加一個節點,方便實現無縫切換,做一些初始化樣式設置
        createNode:function(){
            var _this=this;
            var nodeBefore=this.ali[0].cloneNode(true);
            var nodeAfter=this.ali[this.len-1].cloneNode(true);
            _this.box.appendChild(nodeBefore);
            _this.box.insertBefore(nodeAfter,this.ali[0]);
            this.newLen=$_(this.option.slideCell+" >ul li").length;
            this.box.style.cssText="width:"+this.newLen*this.aliWidth+"px;"+"position:absolute;"+" left:"+(-this.aliWidth)+"px";
            this.wrap.style.cssText="height:"+this.aliHeight+"px";
           for(var i=0;i<this.newLen;i++){
              var oli=$_(this.option.mainCell)[0].children[i];
              oli.style.cssText="float:left;"+"width:"+this.aliWidth+"px";
            }
        },
        //創建
        create_page:function(){
            var _this=this;
            //生成自動分頁的導航
            if(this.option. autoPage==true){
                var ali="";
                for(var i=0;i<this.len;i++){
                    ali+="<li>"+(i+1)+"</li>";
                }
                var oul=$_(this.option.titCell)[0];
                oul.innerHTML=ali;
            }
            this.tit=$_(this.option.titCell+" li");
            this.tit[_this.iNow].className="on";
            for(var i=0;i<this.tit.length;i++){
                this.tit[i].pos=i;
                this.tit[i].onclick=function(){
                    clearInterval(_this.timer);
                    var currNum=this.pos;
                    var dir=currNum-_this.iNow;
                    if(_this.state==true){
                        _this.handle();
                    }
                    else{
                        _this.startOffset=_this.box.offsetLeft;
                    }
                    _this.animate(-_this.aliWidth*dir);
                    _this.iNow=currNum;

                }
            }
        },
        //處理動畫沒有結束滑動的bug
        handle:function(){
            var _this=this;
            clearInterval(_this.transition);
            _this.endX=_this.endX<=-(_this.newLen-1)*_this.aliWidth?-(_this.aliWidth):_this.endX;
            _this.endX=_this.endX>=0?-(_this.newLen-2)*_this.aliWidth:_this.endX;
            _this.startOffset=_this.endX;
        }
        ,
        //添加滑動事件
        addEvent:function(){
            var _this=this;var startX=0;this.startOffset=-_this.aliWidth;var movex=0;this.endX=0;this.state=false;
            _this.wrap.addEventListener("touchstart",start,false);
            _this.wrap.addEventListener("touchmove",move,false);
            _this.wrap.addEventListener("touchend",end,false);
            function start(e){
                var e=e||window.event;
                clearInterval(_this.timer);
                if(_this.state==true){
                    _this.handle();
                }
                else{
                    clearInterval(_this.transition);
                    startX= e.touches[0].clientX;
                    _this.startOffset=_this.box.offsetLeft;
                }
            }
            function move(e){
                var e=e||window.event;
                _this.movex= e.touches[0].clientX-startX;
                _this.box.style.left=_this.startOffset+_this.movex+"px";
            }
            function end(e){
                var left = _this.box.offsetLeft;
                var currNum = left/_this.aliWidth;
                var pointX=left%_this.aliWidth;
                if(_this.movex<0){
                    if(Math.abs(_this.movex)<30){
                        _this.animate(0)
                    }
                    else{
                        _this.animate(-_this.aliWidth)
                    }
                }
                else{
                    if(Math.abs(_this.movex)<30){
                        _this.animate(0)
                    }
                    else{
                        _this.animate(_this.aliWidth)
                    }
                }
            }
        },
        //封裝一個動畫函數
        animate:function(offset){
            var _this=this;var interval=10;_this.state=true;_this.endX=_this.startOffset+offset;

            var offsetX=(_this.endX-_this.startOffset)/this.aliWidth;
                _this.tit[_this.iNow].className="";
                _this.iNow-=offsetX;
                _this.iNow=_this.iNow>=this.len?0:_this.iNow;
                _this.iNow=_this.iNow<0?4:_this.iNow;
                _this.tit[_this.iNow].className="on";
            _this.transition=setInterval(move,10);
            function move(){
                var speed=(_this.endX-_this.box.offsetLeft)/20;
                speed=speed>0?Math.ceil(speed):Math.floor(speed);
                if(parseInt(_this.box.style.left)==-(_this.newLen-1)*_this.aliWidth){
                    _this.box.style.left=-(_this.aliWidth)+"px";
                    _this.endX=-(_this.aliWidth);
                }
                if(parseInt(_this.box.style.left)==0){
                    _this.box.style.left=-(_this.newLen-2)*_this.aliWidth+"px";
                    _this.endX=-(_this.newLen-2)*_this.aliWidth;
                }
                _this.box.style.left=_this.box.offsetLeft+speed+"px";
                if(speed==0){
                    clearInterval(_this.transition);
                      if(_this.option.autoPlay==true){
                        clearInterval(_this.timer);
                          _this.timer=setInterval(_this.auto_play(),_this.option.interTime)
                    }
                    _this.box.style.left=_this.endX+"px";
                    _this.state=false;
                }
            }
        },
        //設置自動播放
        auto_play:function(){
            var _this=this;
            return function(){
                     clearInterval(_this.timer);
                    _this.startOffset=_this.box.offsetLeft;
                    _this.animate(-_this.aliWidth);

            }
        }

    }
    window.mslider=mslider;//暴露給全局,方便調用
})();

下面是html結構

<div>
    <h2 class="title">手機端輪播實現</h2>
    <div class="wrap">
        <ul class="clearfix box">
            <li><img src="image/f1.jpg" alt=""></li>
            <li><img src="image/f2.jpg" alt=""></li>
            <li><img src="image/f3.jpg" alt=""></li>
            <li><img src="image/f4.jpg" alt=""></li>
            <li><img src="image/f5.jpg" alt=""></li>
        </ul>
    </div>
    <div class="hd">
        <ul>

        </ul>
    </div>
</div>
<script>
    new mslider({
        slideCell:".wrap",
        titCell:".hd ul",
        mainCell:".box",
        interTime:3000,
        autoPlay:false, //自動播放
        autoPage:true,//自動分頁
    });
</script>

附上我的demo github地址,https://github.com/shentaochok/mslider.git,並沒有css,我都寫在了js里面,可以直接調用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM