移動端輪播圖原生實現

實現移動端滑動輪播和定時輪播

  1. slidebanner.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <title>移動端-輪播圖</title>
    <link rel="stylesheet" href="slideshow.css">
</head>
<body>
<div class="layout">
    <div class="banner">
        <ul class="clearfix">
            <li><a href="#"><img src="images/5.jpg"></a></li>
            <li><a href="#"><img src="images/1.jpg"></a></li>
            <li><a href="#"><img src="images/2.jpg"></a></li>
            <li><a href="#"><img src="images/3.jpg"></a></li>
            <li><a href="#"><img src="images/4.jpg"></a></li>
            <li><a href="#"><img src="images/5.jpg"></a></li>
            <li><a href="#"><img src="images/1.jpg"></a></li>
        </ul>
        <ul>·
            <li class="now"></li>
            <li></li>
            <li></li>
            <li></li>
            <li></li>
        </ul>
    </div>
</div>

<script src="base.js"></script>
<script src="slideshow.js"></script>
</body>
</html>
  1. slidebanner.css
*,
::before,
::after{
    padding: 0;
    margin: 0;
    -webkit-box-sizing: border-box;/*兼容移動端主流瀏覽器*/
    box-sizing: border-box;
    -webkit-tap-highlight-color: transparent;/*清除移動端點擊高亮效果*/
}
body{
    font-family:Microsoft YaHei,sans-serif;/*移動端默認的字體*/
    font-size: 14px;
    color: #333;
}
ol,ul{
    list-style: none;
}
/*清除浮動*/
.clearfix::before,
.clearfix::after{
    content: "";
    display: block;
    height: 0;
    line-height: 0;
    visibility: hidden;
    clear: both;
}

.layout{
    width: 100%;
    max-width: 750px;
    min-width: 320px;
    margin: 0 auto;
    position: relative;
}
.banner{
    width: 100%;
    height: 300px;
    overflow: hidden;
    position: relative;
}
.banner ul:first-child{
    width: 1000%;
    height: 300px;
    -webkit-transform: translateX(-10%);
    transform: translateX(-10%);
}
.banner ul:first-child li{
    width: 10%;
    height: 100%;
    float: left;
}
.banner ul:first-child li a{
    display: block;
    width: 100%;
    height: 100%;
}
.banner ul:first-child li a img{
    width: 100%;
    height: 100%;
    display: block;
}
.banner ul:last-child{
    position: absolute;
    bottom: 6px;
    width: 100%;
    text-align: center;
}
.banner ul:last-child li{
    width: 6px;
    height: 6px;
    border: 1px solid #fff;
    border-radius: 50%;
    display: inline-block;
    margin-left: 10px;
}
.banner ul:last-child li:first-child{
    margin-left: 0;
}
.banner ul:last-child li.now{
    background: #fff;
}
  1. slidebanner.js
/*封裝一些公用的事件或者公用的方法*/
/*定義的一個命名空間*/
window.S = {};
/*封裝一個事件 過渡結束事件*/
S.transitionEnd = function(dom,callback){
    //1.給誰加事件
    //2.事件觸發後處理什麼業務
    if(!dom || typeof dom != 'object'){
        //沒dom的時候或者不是一個對象的時候 程序停止
        return false;
    }
    dom.addEventListener('transitionEnd', function(){
        callback && callback();
    });
    dom.addEventListener('webkitTransitionEnd', function(){
        callback && callback();
    });
}

window.onload = function(){
    /*
     * 1.自動輪播  定時器  無縫銜接  動畫結束瞬間定位
     * 2.點需要隨着輪播的滾動改變對應的點  改變當前樣式  當前圖片的索引
     * 3.手指滑動的時候讓輪播圖滑動   touch事件  記錄座標軸的改變 改變輪播圖的定位(位移css3)
     * 4.當滑動的距離不超過一定的距離的時候  需要吸附回去  過渡的形式去做
     * 5.當滑動超過了一定的距離  需要 跳到 下一張或者上一張  (滑動的方向) 一定的距離(屏幕的三分之一)
     * */

    var imageCount = 5; //頁面中用來輪播的圖片有5張不同的
    //輪播圖大盒子
    var banner = document.querySelector('.banner');
    //圖片的寬度
    var width = banner.offsetWidth;
    //圖片盒子
    var imageBox = banner.querySelector('ul:first-child');
    //點盒子
    var pointBox = banner.querySelector('ul:last-child');
    //所有的點
    var points = pointBox.querySelectorAll('li');

    //公用方法
    //加過渡
    var addTransition = function(){
        imageBox.style.transition = "all 0.3s";
        imageBox.style.webkitTransition = "all 0.3s";/*做兼容*/
    };
    //清除過渡
    var removeTransition = function(){
        imageBox.style.transition = "none";
        imageBox.style.webkitTransition = "none";
    }
    //定位
    var setTranslateX = function(translateX){
        imageBox.style.transform = "translateX("+translateX+"px)";
        imageBox.style.webkitTransform = "translateX("+translateX+"px)";
    }

    //功能實現
    //自動輪播  定時器  無縫銜接  動畫結束瞬間定位
    var index = 1;
    var timer = setInterval(function(){
        index++ ;   //自動輪播到下一張
        //改變定位  動畫的形式去改變  transition transform translate
        addTransition();    //加過渡動畫
        setTranslateX(-index * width);  //定位
    },3000);

    //等過渡結束之後來做無縫銜接
    S.transitionEnd(imageBox, function(){
        //處理事件結束後的業務邏輯
        if(index > imageCount ){
            index = 1;
        }else if(index <= 0){
            index = imageCount;
        }
        removeTransition(); //清除過渡
        setTranslateX(-index * width);  //定位
        setPoint(); //設置底部顯示當前圖片對應的圓角
    });

    //改變當前樣式  當前圖片的索引
    var setPoint = function(){
        //清除上一次的now
        for(var i = 0 ; i < points.length ; i++){
            points[i].className = " ";
        }
        //給圖片對應的點加上樣式
        points[index-1].className = "now";
    }

    /*
     手指滑動的時候讓輪播圖滑動   touch事件  記錄座標軸的改變 改變輪播圖的定位(位移css3)
     當滑動的距離不超過一定的距離的時候  需要吸附回去  過渡的形式去做
     當滑動超過了一定的距離  需要 跳到 下一張或者上一張  (滑動的方向) 一定的距離(屏幕的三分之一)
     */
    //touch事件
    var startX = 0; //記錄起始  剛剛觸摸的點的位置 x的座標
    var moveX = 0;  //滑動的時候x的位置
    var distanceX = 0;  //滑動的距離
    var isMove = false; //是否滑動過

    imageBox.addEventListener('touchstart', function(e){
        clearInterval(timer);   //清除定時器
        startX = e.touches[0].clientX;  //記錄起始X
    });

    imageBox.addEventListener('touchmove',function(e){
        moveX = e.touches[0].clientX;   //滑動時候的X
        distanceX = moveX - startX; //計算移動的距離
        //計算當前定位  -index*width+distanceX
        removeTransition(); //清除過渡
        setTranslateX(-index * width + distanceX);  //實時的定位
        isMove = true;  //證明滑動過
    });

    //在模擬器上模擬的滑動會有問題 丟失的情況  最後在模擬器的時候用window
    imageBox.addEventListener('touchend', function(e){
        // 滑動超過 1/3 即爲滑動有效,否則即爲無效,則吸附回去
        if(isMove && Math.abs(distanceX) > width/3){
            //5.當滑動超過了一定的距離  需要 跳到 下一張或者上一張  (滑動的方向)*/
            if(distanceX > 0){  //上一張
                index --;
            }
            else{   //下一張
                index ++;
            }
        }
        addTransition();    //加過渡動畫
        setTranslateX(-index * width);    //定位

        if(index > imageCount ){
            index = 1;
        }else if(index <= 0){
            index = imageCount;
        }
        setPoint();

        //重置參數
        startX = 0;
        moveX = 0;
        distanceX = 0;
        isMove = false;
        //加定時器
        clearInterval(timer);   //嚴謹 再清除一次定時器
        timer= setInterval(function(){
            index++ ;  //自動輪播到下一張
            addTransition();    //加過渡動畫
            setTranslateX(-index * width);    //定位
        },3000);
    });
};

4.核心代碼解釋

// 第一步
// 首尾兩張圖片是爲了滑動時的過渡,當JS監聽到此時滑動到是最後一張或者第一張的時候,
// 會分別自動地切換到倒數第二張(肉眼看到的最後一張)或者第二張圖片(肉眼看到的第一張)
 <li><a href="#"><img src="images/5.jpg"></a></li>
 <li><a href="#"><img src="images/1.jpg"></a></li>
 <li><a href="#"><img src="images/2.jpg"></a></li>
 <li><a href="#"><img src="images/3.jpg"></a></li>
 <li><a href="#"><img src="images/4.jpg"></a></li>
 <li><a href="#"><img src="images/5.jpg"></a></li>
 <li><a href="#"><img src="images/1.jpg"></a></li>


// 第二步
// 上面說到的監聽會在transition結束後進行,
// 例如,要展示的圖片共5張,此時滑到了第七張(也就是最後一張圖片,同時也是我們肉眼看到的第一張圖片),
// 監聽到這種情況發生後,就會將位置移動到第二張(還是我們肉眼看到的第一張),但是這次移動是沒有過渡效果,速度很快,
// 所以肉眼看不出來圖片被我們替換了(因爲是同一張圖片,並且速度快,肉眼看不出位置已經被替換了)
// 同理,左滑滑到了第一張圖片也是這樣的處理邏輯。
S.transitionEnd(imageBox, function(){
    //處理事件結束後的業務邏輯
    if(index > imageCount ){
        index = 1;
    }else if(index <= 0){
        index = imageCount;
    }
    removeTransition(); //清除過渡
    setTranslateX(-index * width);  //定位
    setPoint(); //設置底部顯示當前圖片對應的圓角
});


// 第三步
//監聽的核心的給dom添加監聽事件'transitionEnd'。
S.transitionEnd = function(dom,callback){
    //1.給誰加事件
    //2.事件觸發後處理什麼業務
    if(!dom || typeof dom != 'object'){
        //沒dom的時候或者不是一個對象的時候 程序停止
        return false;
    }
    dom.addEventListener('transitionEnd', function(){
        callback && callback();
    });
    dom.addEventListener('webkitTransitionEnd', function(){
        callback && callback();
    });
}


// 第四步
// 用JS添加CSS樣式,添加過渡效果
var addTransition = function(){
   imageBox.style.transition = "all 0.3s";
   imageBox.style.webkitTransition = "all 0.3s";/*做兼容*/
};


// 第五步
// 動態去改變輪播的位置
var setTranslateX = function(translateX){
    imageBox.style.transform = "translateX("+translateX+"px)";
    imageBox.style.webkitTransform = "translateX("+translateX+"px)";
}


// 第六步
// 手指觸摸屏幕的時候('touchstart'),記得清楚定時器
// 手指離開屏幕的時候('touchend'),記得添加回定時器
var removeTransition = function(){
    imageBox.style.transition = "none";
    imageBox.style.webkitTransition = "none";
}

5.效果圖如下
輪播圖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章