1. 程式人生 > >原生js實現簡單移動端輪播圖

原生js實現簡單移動端輪播圖

1、程式碼部分

  分為四個檔案:

  slideshow.html

  slideshow.css

  base.js

  slideshow.js

1.1、slideshow.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/l5.jpg"></a></li>
            <li><a href="#"><img src="images/l1.jpg"></a></li>
            <li><a href="#"><img src="images/l2.jpg"></a></li>
            <li><a href="#"><img src="images/l3.jpg"></a></li>
            <li><a href="#"><img src="images/l4.jpg"></a></li>
            <li><a href="#"><img src="images/l5.jpg"></a></li>
            <li><a href="#"><img src="images/l1.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.2、slideshow.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%;
    overflow: hidden;
    position: relative;
}
.banner ul:first-child{
    width: 1000%;
    -webkit-transform: translateX(-10%);
    transform: translateX(-10%);
}
.banner ul:first-child li{
    width: 10%;
    float: left;
}
.banner ul:first-child li a{
    display: block;
    width: 100%;
}
.banner ul:first-child li a img{
    width: 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.3、base.js

複製程式碼
/*封裝一些公用的事件或者公用的方法*/
/*定義的一個名稱空間*/
window.my = {};
/*封裝一個事件 過渡結束事件*/
my.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();
    });
}

//封裝一個tap事件
my.tap = function(dom,callback){
    if(!dom || typeof dom != 'object'){
        //沒dom的時候或者不是一個物件的時候 程式停止
        return false;
    }

    var isMove = false; //是否滑動過
    var time = 0;   //剛剛觸控式螢幕幕的事件  touchstart的觸發事件

    dom.addEventListener('touchstart',function(){
        //記錄觸發這個事件的時間
        time = Date.now();  //時間戳 毫秒
    });
    dom.addEventListener('touchmove',function(){
        isMove = true;
    });
    window.addEventListener('touchend',function(e){
        //1.沒有滑動過
        //2.響應事件在150ms以內   要求比click要響應快
        if(!isMove && (Date.now()-time)<150 ){
            callback && callback(e);
        }

        //重置引數
        isMove = false;
        time = 0;
    });

}
複製程式碼

1.4、slideshow.js

複製程式碼
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);

    //等過渡結束之後來做無縫銜接
    my.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);
    });
};
複製程式碼

 

2、效果