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

2024/04/02閱讀時間約 7 分鐘
raw-image

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

先附上最終結果的 codepen


再來記錄一下實作過程

切出畫面

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

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

這次會先做簡單的單張圖片輪播,所以輪播框架和輪播圖片區基本上看起來會一樣大,依照這樣的架構思路來切版, 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,前端學習中,歡迎交流討論🧸

    20會員
    18內容數
    留言0
    查看全部
    發表第一個留言支持創作者!