1. 程式人生 > >JS原生輪播圖方法及技巧

JS原生輪播圖方法及技巧

主要涉及知識點,元素的獲取,計時器,開關鎖,速度位子的變化

1.設計思路

輪播圖設計思路,控制ul在一定時間內,向右移動一個 li 寬度的距離,從而展示相應 li 的圖片內容,當移動到最後一個li時,迅速讓其座標歸0,從新開始迴圈。

新增向左或向右按鈕,繫結點選按鈕與ul的關係,當點擊向左時,ul + 一個 li 的寬度,當點擊向右時,ul - 一個 li 的寬度,當ul在最左側時候,讓其座標點迅速變成最有一個 li,開始迴圈。

新增輪播圖下方小點,建立一個計數器,繫結到 ul 上,當ul 向右移動時,計數器++,到最後一個 li 時候,計數器 歸 0,當ul向左移動時 計數器--;到最左側第一個 li 時,迅速賦值為 最後一位,開始迴圈。

新增小點點選事件,for迴圈所有小點,當點選到當前 小點時,控制ul移動到 當前對應 li 位子上。

2.HTML,CSS方面

css


        *{
            padding: 0px;
            margin: 0px;
            list-style: none;
        }
        .warpper{
            position: relative;
            width: 400px;
            height: 300px;
            margin: 100px auto 0;
            overflow: hidden;
        }
        .warpper .sliderPage{
            position: absolute;
            left: 0px;
            top: 0px;
            width: 2000px;
            height: 300px;

        }
        .warpper .sliderPage li{
            width: 400px;
            height: 300px;
            float: left;
        }
        .warpper .sliderPage li img{
            width: 100%;     
            height: 100%;      
        }
        .warpper .btn{
            position: absolute;
            top: 50%;
            margin-top: -20px;
            width: 40px;
            height: 40px;
            font-size: 30px;
            color: #ccc;
            text-align: center;
            background: #000;
            opacity: 0.2;
            cursor: pointer;
        }
        .warpper .btn:hover{
            opacity: 0.6;
        }
        .warpper .leftbtn{
            left: 10px;
        }
        .warpper .rightbtn{
            right: 10px;
        }
        .warpper .sliderIndex{
           
            position: absolute;
            width: 100%;
            bottom: 15px;
            text-align: center;
            cursor: pointer;
            
        }
        .warpper .sliderIndex span{
            display: inline-block;
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: #555;
            margin-right: 10px;
        }
        .warpper .sliderIndex .active{
            background-color: red;
        }

html5

 <div class="warpper">
        <ul class="sliderPage">
            <li><img src="./tu1.jpg" alt=""></li>
            <li><img src="./tu2.jpg" alt=""></li>
            <li><img src="./tu3.jpg" alt=""></li>
            <li><img src="./tu4.jpg" alt=""></li>
            <li><img src="./tu1.jpg" alt=""></li>
        </ul>
        <div class="btn leftbtn">&lt;</div>
        <div class="btn rightbtn">&gt;</div>
        <div class="sliderIndex">
            <span class="active"></span>
            <span></span>
            <span></span>
            <span></span>
        </div>
    </div>

3.JS方面

1.書寫運動程式碼

//獲取元素屬性的封裝方法
function getStyle (obj, attr) {
    if (obj.currentStyle) {
        return obj.currentStyle[attr];
    }else {
        return window.getComputedStyle(obj, false)[attr];
    }
}
//運動事件函式
function startMove (obj, data, func) {         
    clearInterval(obj.timer);
    var iSpeed; //速度
    var iCur;    
    var name;            
    startTimer = obj.timer = setInterval(function () {
        var bStop = true;
        //遍歷 data
        for (var attr in data) {
            if (attr === 'opacity') {
                name = attr;
        //當 data 內屬性 是 opacity時,數值擴大100倍
                iCur = parseFloat(getStyle(obj, attr)) * 100;
            }else {
                iCur = parseInt(getStyle(obj, attr));
            }
        // 當前屬性值 減去 原屬性值
            iSpeed = ( data[attr] - iCur) / 5;
        // 速度 大於0 向上取整, 小於0,向下取整
            if (iSpeed > 0) {
                iSpeed = Math.ceil(iSpeed);
            }else {
                iSpeed = Math.floor(iSpeed);
            }
            // 當屬性為 opacity時,賦值時 值縮小100倍
            if (attr === 'opacity') {
                obj.style.opacity = ( iCur + iSpeed ) / 100; 
            }else {
                obj.style[attr] = iCur + iSpeed + 'px';
            }
            if ( Math.floor(Math.abs(data[attr] - iCur)) != 0 ) {
            //當速度不為0時,不停止
                bStop = false;
            }
        }
        // 當bStop為true時, 清除定時器
        if (bStop) {					
            clearInterval(obj.timer);
            if (name === 'opacity') {
                obj.style.opacity = data[name] / 100;
            }
            func();
        }
    },30);
}  

2.書寫輪播圖程式碼

分為四步,第一部先寫自動向右,第二部新增兩側按鈕,第三部新增底部小點效果,第四部新增小點點選事件。

 var timer = null;
        var sliderPage = document.getElementsByClassName('sliderPage')[0];//獲取ul
        var moveWidth = sliderPage.children[0].offsetWidth;//獲取li寬度
        var num = sliderPage.children.length - 1;//獲取li數量
        var leftBtn = document.getElementsByClassName('leftBtn')[0];//獲取左側點選
        var rightBtn = document.getElementsByClassName('rightBtn')[0];//獲取右側點選
        var oSpanArray = document.getElementsByClassName('sliderIndex')[0].getElementsByTagName('span');//獲取底部小點
        var lock = true;//加鎖
        var index = 0;//小點計數器
            
        //第一步,向左向右翻動
         // direction 控制方向
        //預設輪播方向/right按鈕  'left->right' / undefined
        //點選left按鈕  'right->left' 
        function autoMove (direction) {
            // 當鎖開時執行
            if (lock) {
                lock = false;
                clearTimeout(timer);
                // 當方向不存在,或者左向右時,ul減去一個li的寬度
                if (!direction || direction == 'left->right') {
                    index++;
                    startMove(sliderPage, {left: sliderPage.offsetLeft - moveWidth}, function () {
                        //當ul 在最後一個li 時,讓其位子歸0,計數器歸0
                        if (sliderPage.offsetLeft == - num * moveWidth) {
                            index = 0;
                            sliderPage.style.left = '0px';
                        }
                        // 計時器開啟,鎖開啟,小點變化
                        timer = setTimeout(autoMove, 1500);
                        lock = true;
                        changeIndex(index);
                    });
     //當右向左時, 在ul在第一個li 位子,就讓其賦值到最後一個li位子,計數器也賦值到最後一個li
                }else if (direction == 'right->left') {
                    if (sliderPage.offsetLeft == 0) {
                        sliderPage.style.left = - num * moveWidth + 'px';
                        index = num;
                    }
        //右向左 計數器 --, ul 加上一個 li的寬度
                    index--;
                    startMove(sliderPage, {left: sliderPage.offsetLeft + moveWidth}, function () {
                //計時器開啟,鎖開啟,小點變化
                        timer = setTimeout(autoMove, 1500);
                        lock = true;
                        changeIndex(index);
                    })
                }
            }
        }

        //第二步,新增左右點選按鈕
        leftBtn.onclick = function () {
            autoMove('right->left');
        }

        rightBtn.onclick = function () {
            autoMove('left->right');
        }
        //第三步,新增小點變化

        function changeIndex (_index) {
            for (var i = 0; i < oSpanArray.length; i++) {
                //迴圈所有小點樣式取消
                oSpanArray[i].className = '';
            }
            //當前小點 新增樣式
            oSpanArray[_index].className = 'active';
        }

        //第四步,新增小點點選事件

        for (var i = 0; i < oSpanArray.length; i++) {
            (function (myIndex) {
                oSpanArray[i].onclick = function () {
        //點選當前小點時,鎖關閉,定時器清除,計數器賦值當前位子,運動到當前位子得li上
                   lock = false;
                   clearTimeout(timer);
                   index = myIndex;
                   startMove(sliderPage, {left: - index * moveWidth}, function () {
                 // 點選事件結束, 鎖開啟,定時器啟動,小點變化
                       lock = true;
                       timer = setTimeout(autoMove, 1500);
                       changeIndex(index);
                   })
                }
            })(i)
        }


  timer = setTimeout(autoMove, 1500);