2024-04-02|閱讀時間 ‧ 約 27 分鐘

切版紀錄 | 來手刻輪播效果吧~

    raw-image

    前幾天和一起轉職的同學分享工作近況的時候,得知他們公司切版時,大部分會手刻,比較少用現成的 UI 套件工具,像輪播效果也是手刻,讓我覺得有點挑戰,決定也來自己手刻一個輪播工具!

    先附上最終結果的 codepen


    再來記錄一下實作過程

    切出畫面

    因為之前很常使用 swiper 做輪播,所以知道最基本的架構會是:

    • 輪播框架 (swiper,包含幻燈片+切換按鈕/scrollbar...等等)
    • 輪播圖片區 (swiper-wrapper,包含多張幻燈片)
    • 單張幻燈片 (swiper-slide)
    • 左右按鈕 (swiper-btn)

    這次會先做簡單的單張圖片輪播,所以輪播框架和輪播圖片區基本上看起來會一樣大,依照這樣的架構思路來切版, HTML 的部分比較沒問題,就是 swiper 包輪播圖片區和左右按鈕,輪播圖片內再去排列單張幻燈片。


    CSS 定位

    輪播效果比較重要的是slide「定位」「移動效果」,所以 CSS 的 position 定位設置好,整個效果就會出來!

    輪播框架 swiper

    width / height 是整個輪播區的大小

    position: relative; 讓按鈕可以定位在幻燈片的左右兩側

    .swiper {
    position: relative;
    max-width: 900px;
    height: 450px;
    margin: 30px auto;
    }


    輪播圖片區 swiper-wrapper

    position: relative; 讓每張 slide 定位在圖片區內,之後會根據切換按鈕去移動 slide 的位置百分比例,達成切換效果

    overflow: hidden; 把定位在左右的兩張圖片隱藏起來

    .swiper-wrapper{
    position: relative;
    overflow: hidden;
    width: 100%;
    height: 100%;
    }


    單張幻燈片 swiper-slide

    transition: all 1s; 切換下一張時可以平滑移動

    left: 100%; 讓所有幻燈片定位在 swiper-wrapper 的外面,只有加上 active 這個 class 的幻燈片會出現在 swiper-wrapper 畫面內

    z-index:1; 讓所有幻燈片的圖層低於 active 的幻燈片

    .swiper-slide {
    width: 100%;
    height: 100%;
    transition: all 1s;
    position: absolute;
    top: 0;
    left: 100%;
    z-index:1;
    }

    .active{
    left: 0%;
    z-index:10;
    }


    剩下的 swiper-imgswiper-btn 就依照自己想設置的位置和樣式去寫就可以了,我的詳細設置可以看 codepen,基本切版雛形完成,目前就會是一個還不能切換的畫面,現在可以開始寫 javascript 讓它動起來了~


    按鈕切換邏輯

    定義變數

    1. 先取得 DOM 元素、所有幻燈片的陣列和綁定按鈕監聽事件
    2. slideIndex要紀錄目前 active slide 所在的陣列位置
    3. sliderPrevIndexslideIndex 的前一張
    4. ​sliderNextIndexslideIndex 的後一張
    const nextBtn = document.querySelector(".swiper-btn-next");
    const preBtn = document.querySelector(".swiper-btn-pre");
    const slide = document.querySelectorAll(".swiper-slide");
    let slideIndex = 0;
    let sliderPrevIndex = 0;
    let sliderNextIndex = 0;
    const slideNumber = slide.length;

    綁訂監聽事件

    1. 按下 next 按鈕時,slideIndex += 1,如果 slideIndex 跑到最後一筆,則 slideIndex = 0
    2. 按下 prev 按鈕,slideIndex 剛好為 0 的情況 slideIndex = 陣列長度 - 1 ,其他情況則 slideIndex - 1
    nextBtn.addEventListener("click", () => {
    if (slideIndex == slideNumber - 1) {
    slideIndex = 0;
    } else {
    slideIndex += 1;
    }
    updateClasses();
    });

    preBtn.addEventListener("click", () => {
    if (slideIndex == 0) {
    slideIndex = slideNumber - 1;
    } else {
    slideIndex -= 1;
    }
    updateClasses();
    });


    跑迴圈加上相應class

    迴圈清除所有幻燈片原本綁定的 active/prev/next class,並根據 slideIndex 為當前的 slide 加上 active,以及前後兩張 slide 分別加上 prev/next 的 class

    function updateClasses() {
    if (slideIndex === 0) {
    sliderPrevIndex = slideNumber - 1;
    } else {
    sliderPrevIndex = slideIndex - 1;
    }

    if (slideIndex === slideNumber - 1) {
    sliderNextIndex = 0;
    } else {
    sliderNextIndex = slideIndex + 1;
    }

    slide.forEach((i) => {
    i.classList.remove("active", "prev", "next");
    });
    slide[slideIndex].classList.add("active");
    slide[sliderPrevIndex].classList.add("prev");
    slide[sliderNextIndex].classList.add("next");
    }


    最後別忘了回到 HTML 去把預設要顯示的第一張 slide 加上 active class,下一張 slide 加上 next class,前一張 slide 加上 prev class,一個簡單的輪播效果就完成了~


    我是Amber,前端學習中,歡迎交流討論🧸

    分享至
    成為作者繼續創作的動力吧!
    © 2024 vocus All rights reserved.