純JS實現輪播圖

寫在前面 

是的,這個輪播圖我看了一天的時間,網上找說明,外加請教別人,自己動手試着寫寫,昨天看了一下午,夜裏又簡單想了一下整個流程。終於今天上午開始動手寫,磕磕絆絆,跌跌撞撞,完整的輪播讓我給實現了。

總的來說,算是完成了,爲啥要說算是呢,因爲自己在獨立地寫的過程中還是會出現一些問題,就會看別人怎麼寫的,怎麼實現的,再去對比一下自己的思路。遇到問題,思考問題,再到解決問題,是個需要不斷重複的過程,只有這樣,纔會讓自己熟練,時間長了,再遇到問題知道如何解決,從哪些地方去檢查。

emmmmmmm,簡單的學習心得分享完畢,開始擼思路,擼代碼吧。

輪播圖

輪播圖功能需求:

 1. 鼠標經過/離開輪播圖時  左右按鈕的顯示/隱藏

 2. 點擊圓點時,圓度變爲當前狀態;圖片切換

 3. 左右按鈕點擊時,輪播圖片

 4. 圖片輪播時 下方的圓點也跟着切換

 5. 鼠標放上焦點圖時 圖片停止自動輪播  ; 鼠標離開時 圖片自動輪播

 需要注意的是,頁面一開始圖片就是輪播着的

優化的地方:

1. 增加節流閥:

當連續點擊按鈕時,一張圖片沒有輪播完就會出現下一張。增加的節流閥的目的就是解決上面所敘述的問題。一般節流閥就是兩種操作,關閉節流閥(鎖函數),打開節流閥(開函數)。

2. 提取代碼相同的部分,單獨作爲一個函數,進行調用。還有就是把一些簡單的if語句的判斷可以使用三元表達式來代替

無縫輪播的思想

無縫輪播的佈局:把放輪播圖的ul中的第一個孩子li,複製一份放到ul的最後。

輪播具體實現的過程:正常的話,用戶點擊按鈕進行圖片的輪播,當用戶看到最後一張圖片(其實是我們佈局中的倒數第二張)時,點擊右側按鈕的時候,用戶看到的是第一張圖片,其本質是用戶看到了我們佈局中的最後一張,因爲這一張圖是我們複製的第一張圖,與此同時,我們悄悄的把ul瞬間回到原位置(left = 0),製造假象,讓用戶以爲是第一張圖片,其實是我們佈局中的最後一張。當用戶再點擊時,因爲此時ul已經瞬間移回到原來的位置,再點擊向右輪播的按鈕,ul就按照正常的輪播到第二張圖片。這樣就實現了無縫輪播。

這是輪播圖中比較重要的一個思想。思路解決了 ,咱們就看代碼吧。

代碼裏面有很詳細的解釋,可以認真看看的。

JS部分

// 輪播圖的需求:
// 1. 鼠標經過/離開輪播圖時  左右按鈕的顯示/隱藏
// 2. 點擊圓點時,圓度變爲當前狀態;圖片切換
// 3. 左右按鈕點擊時,輪播圖片
// 4. 圖片輪播時 下方的圓點也跟着切換
// 5. 鼠標放上焦點圖時 圖片停止自動輪播  ; 鼠標離開時 圖片自動輪播
// 需要注意的是,頁面一開始圖片就是輪播着的
window.addEventListener('load', function () {

    // 1. 鼠標經過輪播圖時 按鈕的顯示和隱藏
    // 獲取事件源
    var focus = document.querySelector('.focus');
    var arrowL = document.querySelector('.arrow-l');
    var arrowR = document.querySelector('.arrow-r');
    var ol = document.querySelector('.circle');
    var ul = focus.querySelector('ul');
    var focusWidth = focus.offsetWidth;
    focus.addEventListener('mouseenter', function () {
        arrowL.style.display = 'block';
        arrowR.style.display = 'block';
        clearInterval(carousel);
        carousel = null;
    })
    focus.addEventListener('mouseleave', function () {
        arrowL.style.display = 'none';
        arrowR.style.display = 'none';
        // 鼠標離開 自動輪播
        carousel = setInterval(function () {
            arrowR.click();
        }, 3000)
    })
    // 2.點擊圓點部分
    // 圓點的個數應該是與圖片的個數是一致的,所以 應該根據ul中的li的個數動態創建圓點的個數
    // js需要寫的具有一定的動態性 改變結構 時 js可以動態生成
    for (var i = 0; i < ul.children.length; i++) {
        // (1)創建圓點 
        var li = document.createElement('li');
        // (2)添加到ol中
        ol.appendChild(li);
        // 設置一個變量 用來記錄當前圓點的索引號 後面與圖片位置對應顯示
        li.setAttribute('index', i);
        // (3).點擊圓點的事件效果 應該在創建之後就綁定事件
        li.addEventListener('click', function () {
            // (4).被點擊的圓點 變成當前狀態
            // 幹掉所有人 ol.children.length所有小圓點的個數
            for (var i = 0; i < ol.children.length; i++) {
                ol.children[i].className = '';
            }
            // 留下我自己 當前點擊的圓點
            this.className = 'current';

            // (5). 點擊時圖片輪播
            // 獲得當前圓點的索引號
            var currentIndex = this.getAttribute('index');
            // 輪播到哪個li 把當前圖片對應的圓點的索引號 給點擊的次數
            // 是保持圓點 按鈕點擊次數 圖片對應一致
            clickCount = currentIndex;
            circleMove = currentIndex;

            // ul移動的距離  圓點索引號*焦點圖的寬度
            animate(ul, -currentIndex * focusWidth);

        })
    }

    // 默認設置第一個圓點爲當前
    ol.children[0].className = 'current';
    // 無縫輪播:把ul中的圖片複製一份到ul的最後。當用戶點擊到最後一張,就是我們的倒數第二張
    // 用戶再點擊時 看到的是第一張的圖片 其實是我們複製了第一張到ul的最後,所以用戶看到的實際上是我們複製的那一張圖
    // 這時當用戶再點擊時  我們迅速把ul移回原位left=0,從頭開始 再按照正常的輪播到第二張


    // 克隆節點在創建小圓點的後面 因爲克隆出來的節點不需要小圓點
    // 複製ul第一個li放到最後 ul.children[0].cloneNode(true)深拷貝
    var firstImg = ul.children[0].cloneNode(true);
    ul.appendChild(firstImg);
    // 點擊按鈕事件
    // 點擊右側按鈕 圖片向左輪播 點擊一次 圖片(ul)移動一個圖片的距離
    // ul移動的距離 = 點擊次數*焦點圖的寬度  與上面點小圓點的效果類似
    // 設置一個變量記錄 點擊的次數  點擊一次圖片滾動一次
    var clickCount = 0;
    // 記錄圓點的位置 控制圓點的播放
    var circleMove = 0;
    // 節流閾值:爲了防止點擊過快圖片沒有輪播完就結束的情況
    var flag = true;
    // 3.右側按鈕點擊
    arrowR.addEventListener('click', function () {
        if (flag) {
            // 先鎖住函數 當動畫執行完畢之後 再解鎖
            flag = false; // 關閉節流閥
            // (1) 當ul走到最後 我們複製的那一張圖片時:ul的left = 0;迅速復原ul
            if (clickCount == ul.children.length - 1) {
                ul.style.left = 0;
                clickCount = 0; // 點擊置0
            }

            clickCount++;
            animate(ul, -clickCount * focusWidth, function () {
                flag = true; // 打開節流閥
            });

            // (2) 圖片輪播時 圓點也在變化
            circleMove++;
            // 當圓點到最後一個4 也就是圖片輪播到我們複製的哪一個圖片時  圓點從頭開始
            if (circleMove == ol.children.length) {
                circleMove = 0
            }
            // circleMove == ol.children.length - 1 ? 0 : circleMove;
            // 調用函數 排他思想
            circleVisible();
        }


    })

    // 4.左側按鈕點擊
    arrowL.addEventListener('click', function () {
        if (flag) {
            flag = false;
            // (1) 當ul是第一張圖片時 點擊時應輪播到倒數第二張 
            if (clickCount == 0) {
                ul.style.left = -clickCount * focusWidth + 'px';
                clickCount = ul.children.length - 1; // 點擊數也回到圖片對應的點擊數
            }
            clickCount--;
            animate(ul, -clickCount * focusWidth, function () {
                flag = true;
            });

            // (2) 圖片輪播時 圓點也在變化
            circleMove--;
            // 點擊時 如果 circleMove < 0 說明是第一張圖片 小圓點要從第4個開始 (索引號3)
            if (circleMove < 0) {
                circleMove = ol.children.length - 1
            }
            // circleMove < 0 ? ol.children.length - 1 : circleMove;
            // 調用函數 排他思想
            circleVisible();
        }
    })

    // 5.鼠標經過時  設置定時器 自動輪播圖片
    // 自動輪播的效果 與點擊右側按鈕的效果一樣
    // 即可以使用手動調取 右側按鈕點擊事件
    var carousel = setInterval(function autoCarousel() {
        arrowR.click();
    }, 3000)

    // 排他
    function circleVisible() {
        // 幹掉所有人
        for (var i = 0; i < ol.children.length; i++) {
            ol.children[i].className = '';
        }
        // 留下自己
        ol.children[circleMove].className = 'current';
    }

})

 

結構部分

這裏有需要注意的一點,輪播圖用到了之前封裝的動畫函數,需要引入動畫的js文件,動畫的js文件要在頁面的js文件之前引入,因爲動畫js是依賴於頁面的js文件的。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css/lb.css">
    <!-- 依賴於lb.js 因爲只有在有js文件時纔會引入動畫函數 所以要在前面引入 -->
    <script src="./js/animate.js"></script>
    <script src="./js/lb.js"></script>
</head>

<body>
    <div class="w">
        <div class="focus">
            <!-- 左側按鈕 -->
            <a href="javascript:;" class="arrow-l">
                
            </a>
            <!-- 右側按鈕 -->
            <a href="javascript:;" class="arrow-r"></a>
            <!-- 核心的滾動區域 -->
            <ul>
                <li>
                    <a href="#"><img src="upload/focus.jpg" alt=""></a>
                </li>
                <li>
                    <a href="#"><img src="upload/focus1.jpg" alt=""></a>
                </li>
                <li>
                    <a href="#"><img src="upload/focus2.jpg" alt=""></a>
                </li>
                <!-- 注意這是第一張圖片複製過來的  -->
                <li>
                    <a href="#"><img src="upload/focus3.jpg" alt=""></a>
                </li>
            </ul>
            <!-- 小圓圈 -->
            <ol class="circle">

            </ol>
        </div>
    </div>

</body>

</html>

 

 

ok,輪播圖克服掉了。

春意盎然,我的寒假還在繼續。。。。。。

 

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