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

閱讀時間約 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,前端學習中,歡迎交流討論🧸

    avatar-img
    22會員
    22內容數
    留言0
    查看全部
    avatar-img
    發表第一個留言支持創作者!
    Amber hh的沙龍 的其他內容
    之前在【什麼是網路請求(HTTP response)】筆記裡有提到,網路請求遇到 CORS 跨域問題,在開發時可以透過 vite 的反向代理來解決,那麼什麼是反向代理,有反向代理的話是不是也有正向代理呢?
    之前分享過【網路請求帶參數的方式】,開發者可以透過 URL 代入參數,來向伺服器請求特定的資源,我們當然也可以擷取 URL 的內容,來做為後續開發的判斷條件,這篇就來記錄一下,網址(URL) 和域名(Domain) 是什麼,以及如何取得網址的參數吧! 我們常說的網址連結 URL 完整名稱是 U
    先前幾篇筆記介紹了網路請求,瀏覽器儲存資料的方式,那麼實務上,前端最常需要發送網路請求的時候,就是透過呼叫 API,去向後端工程師發送/請求資料,所以今天來記錄什麼是 API吧!
    之前在 學習筆記 | 關於 Cookie、Session、Token 這篇筆記有提到,瀏覽器需要帶著使用者的身分訊息或經過身分驗證後取得的Token(令牌),才能向伺服器請求資源,那麼瀏覽器就必須有個空間來儲存這些 Token 資訊,這篇就是要來記錄瀏覽器常見的儲存空間啦~
    上一篇筆記講到了瀏覽器與伺服器之間,經過身分驗證後,就會改以 Token 這個令牌作為通行證,不需要再反覆驗證,那麼這篇紀錄的就是目前最常使用的 JWT (JSON Web Token) 啦! 可以搭配 JWT 的網站來玩看看 JWT(JSON Web Token) 顧名思義就是以 JSON
    延續先前的筆記,「網路請求」是瀏覽器和伺服器的溝通橋梁,目的是為了取得資料庫內的資源,除了 CORS 這種瀏覽器本身的阻擋機制,伺服器也會需要進行「身分驗證或授權」這道阻擋,並不是使用者有帶上 header 告知身分,就一定可以把資料 response 回來的。
    之前在【什麼是網路請求(HTTP response)】筆記裡有提到,網路請求遇到 CORS 跨域問題,在開發時可以透過 vite 的反向代理來解決,那麼什麼是反向代理,有反向代理的話是不是也有正向代理呢?
    之前分享過【網路請求帶參數的方式】,開發者可以透過 URL 代入參數,來向伺服器請求特定的資源,我們當然也可以擷取 URL 的內容,來做為後續開發的判斷條件,這篇就來記錄一下,網址(URL) 和域名(Domain) 是什麼,以及如何取得網址的參數吧! 我們常說的網址連結 URL 完整名稱是 U
    先前幾篇筆記介紹了網路請求,瀏覽器儲存資料的方式,那麼實務上,前端最常需要發送網路請求的時候,就是透過呼叫 API,去向後端工程師發送/請求資料,所以今天來記錄什麼是 API吧!
    之前在 學習筆記 | 關於 Cookie、Session、Token 這篇筆記有提到,瀏覽器需要帶著使用者的身分訊息或經過身分驗證後取得的Token(令牌),才能向伺服器請求資源,那麼瀏覽器就必須有個空間來儲存這些 Token 資訊,這篇就是要來記錄瀏覽器常見的儲存空間啦~
    上一篇筆記講到了瀏覽器與伺服器之間,經過身分驗證後,就會改以 Token 這個令牌作為通行證,不需要再反覆驗證,那麼這篇紀錄的就是目前最常使用的 JWT (JSON Web Token) 啦! 可以搭配 JWT 的網站來玩看看 JWT(JSON Web Token) 顧名思義就是以 JSON
    延續先前的筆記,「網路請求」是瀏覽器和伺服器的溝通橋梁,目的是為了取得資料庫內的資源,除了 CORS 這種瀏覽器本身的阻擋機制,伺服器也會需要進行「身分驗證或授權」這道阻擋,並不是使用者有帶上 header 告知身分,就一定可以把資料 response 回來的。
    你可能也想看
    Google News 追蹤
    經過了一個週末伙伴們在群組問了剪輯的操作問題。覺得大家雖然不熟悉這個領域,但慢慢的進步很好。這幾天我也在思考跨部門合作的優點,設計層面我們提供基礎概念配合業務的專業知識與應對經驗,由於業務部更接近人群知道客戶的痛點,或許會發現我們看不到的層面。這樣互相分享各自的經驗,互相學習一起進步的氛圍,不管是個
    Thumbnail
    可能包含敏感內容
    之後應該都是自動鉛筆畫的
    Thumbnail
    最近幫忙弄了貼圖, 寫個心得來小小紀念一下~ 不囉嗦,先上圖~
    經過了一個週末伙伴們在群組問了剪輯的操作問題。覺得大家雖然不熟悉這個領域,但慢慢的進步很好。這幾天我也在思考跨部門合作的優點,設計層面我們提供基礎概念配合業務的專業知識與應對經驗,由於業務部更接近人群知道客戶的痛點,或許會發現我們看不到的層面。這樣互相分享各自的經驗,互相學習一起進步的氛圍,不管是個
    Thumbnail
    可能包含敏感內容
    之後應該都是自動鉛筆畫的
    Thumbnail
    最近幫忙弄了貼圖, 寫個心得來小小紀念一下~ 不囉嗦,先上圖~