iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0
Modern Web

在Vibe Coding 時代一起來做沒有AI感的漂亮網站吧!系列 第 23

Swiper.js 進階:別再只用小圓點!用 `renderBullet` 打造獨一無二的導航分頁,寫原生JS的請進

  • 分享至 

  • xImage
  •  

嗨咿,我是 illumi!今天跟大家一起用純Js做輪播圖,只要去Swiper官網複製,就可以得到輪播圖!
但預設的小圓點分頁 (pagination) 有點單調,怎麼辦呢?

可以用 Swiper.js 的 pagination 設定! 使用 renderBullet 這個強大的客製化函式,將原本樸素的小圓點,改造成一個帶有標題和描述的互動式菜單。

https://ithelp.ithome.com.tw/upload/images/20250924/20178506bSjOUilu9A.png

改造前:官方的垂直輪播範例

https://ithelp.ithome.com.tw/upload/images/20250924/20178506qnlZqt7b1n.png

你可以在 Swiper 官方提供的 Demo 頁面,點開屬於你的框架,進入到沙盒。

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

<head>
  <meta charset="utf-8" />
  <title>Swiper demo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1" />
  <!-- Link Swiper's CSS -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.css" />

  <!-- Demo styles -->
  <style>
    html,
    body {
      position: relative;
      height: 100%;
    }

    body {
      background: #000;
      font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
      font-size: 14px;
      color: #fff;
      margin: 0;
      padding: 0;
    }

    .swiper {
      width: 100%;
      height: 100%;
    }

    .swiper-slide {
      text-align: center;
      font-size: 18px;
      background: #444;
      display: flex;
      justify-content: center;
      align-items: center;
    }

    .swiper-slide img {
      display: block;
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
  </style>
</head>

<body>
  <!-- Swiper -->
  <div class="swiper mySwiper">
    <div class="swiper-wrapper">
      <div class="swiper-slide">Slide 1</div>
      <div class="swiper-slide">Slide 2</div>
      <div class="swiper-slide">Slide 3</div>
      <div class="swiper-slide">Slide 4</div>
      <div class="swiper-slide">Slide 5</div>
      <div class="swiper-slide">Slide 6</div>
      <div class="swiper-slide">Slide 7</div>
      <div class="swiper-slide">Slide 8</div>
      <div class="swiper-slide">Slide 9</div>
    </div>
    <div class="swiper-pagination"></div>
  </div>

  <!-- Swiper JS -->
  <script src="https://cdn.jsdelivr.net/npm/swiper@11/swiper-bundle.min.js"></script>

  <!-- Initialize Swiper -->
  <script>
    var swiper = new Swiper(".mySwiper", {
      direction: "vertical",
      pagination: {
        el: ".swiper-pagination",
        clickable: true,
      },
    });
  </script>
</body>

</html>

這個範例很直觀,HTML 裡有一個 .swiper-pagination 的 div,然後在 JavaScript 中將它指定為 pagination 的 el。效果就是我們常見的、可點擊切換的垂直小圓點。

但我希望把小圓點改成文字。

改造後:實現客製化菜單分頁

我們的目標是將分頁變成像下圖這樣的菜單:

要達成這個效果,關鍵就在 Swiper 的 pagination 設定中的 renderBullet 函式。

步驟 1:準備你的資料

首先,我們需要一個資料陣列來存放每個分頁要顯示的內容。

javascript

 Show full code block
const menuList = [
  {
    title: "",
    description: "夏季菜單",
  },
  {
    title: "白玫瑰冰晶閃光晶球",
    description: "白玫瑰凍 × 晶化香梨泡沫",
  },
  {
    title: "北極之珠佐杏仁乳雲霧",
    description: "冰晶葡萄球 × 分子杏仁奶霧",
  },
// ... 更多菜單項目
];

步驟 2:修改 Swiper 初始化程式碼

接下來,我們來修改 Swiper 的初始化腳本。注意看 pagination 物件裡的變化。

javascript

 Show full code block
let swiper = new Swiper("#foodSwiper", {
  direction: "vertical",
  loop: true,// 循環播放mousewheel: true,// 支援滑鼠滾輪autoplay: {
    delay: 4500,
    disableOnInteraction: true,// 使用者互動後停止自動播放
  },
  pagination: {
    el: ".food-swiper-pagination",// 指定我們的分頁容器clickable: true,
    bulletClass: "food-swiper-pagination-bullet", // 自訂 bullet class
    bulletActiveClass: "food-swiper-pagination-bullet-active", // 自訂 active class
	// 重點
		renderBullet: function (index, className) {
	// 如果是循環模式,索引值會一直增加,所以用取餘數的方式確保能對應到 menuListconst menuItem = menuList[index % menuList.length];

// 回傳你想要的 HTML 結構return `
        <span class="${className}">
          <strong>${menuItem.title}</strong>
          <p class="text-sm text-black/35">${menuItem.description}</p>
        </span>
      `;
    },
  },
});

renderBullet 函式詳解

renderBullet: function (index, className) 接收兩個參數:

  1. index:目前分頁項目的索引值,從 0 開始。
  2. className:Swiper 預設會為每個分頁項目(bullet)生成的 class 名稱,通常是 swiper-pagination-bullet。我們必須把它加到我們自訂的元素上,Swiper 才能正確地控制它的狀態(例如 active 狀態)。

在這個函式中,我們:

  1. 根據傳入的 index 從 menuList 中找到對應的菜單資料。
  2. 使用樣板字面值 (Template Literal) 建立一個包含 <strong> 和 <p> 標籤的 HTML 字串。
  3. 將 menuItem 的 title 和 description 填入。
  4. 回傳這個 HTML 字串。

Swiper 就會用回傳的 HTML 來取代原本的小圓點。

步驟 3:HTML 與 CSS

HTML:

 <div
        class="swiper mySwiper flex align-center w-full h-full relative"
        id="foodSwiper"
      >
        <button>立即訂位</button>
        <div class="swiper-wrapper z-30">
          <div class="swiper-slide">
            <video autoplay muted loop class="object-cover w-full h-dvh">
              <source
                src="./video/res3-1.mp4"
                type="video/mp4"
                class="object-cover"
              />
            </video>
          </div>
          //其他slide
        </div>
      </div>

CSS : 

在css檔案中放入(我這個案例是這樣寫)

.food-swiper-pagination-bullet {
  line-height: 20px;
  padding: 8px;
  font-size: 20px;
  color: rgb(49, 48, 48);
  opacity: 1;
  display:block;
  cursor: pointer;
  
}

.food-swiper-pagination-bullet-active {
background-image: linear-gradient(to right, #accbee 0%,rgba(255,0,0,0) 100%);
}

補充:關於 autoplay 的使用者體驗優化

在 Script 中可以加入這個!


document.querySelector("#foodSwiper").addEventListener("wheel", () => {
  swiper.autoplay.stop();// 停止自動播放
  swiper.autoplay.start();// 重新啟動自動播放
});

在 Swiper 設定中,啟用了 autoplay 和 mousewheel。這代表輪播會自動播放,但使用者也可以用滑鼠滾輪來切換。

想像一個情境:當輪播正準備在 1 秒後自動切換到下一張時,使用者剛好用滾輪切換了 slide。如果沒有做任何處理,那 1 秒後,輪播還是會再次跳轉,這會打斷使用者的瀏覽,體驗不是很好。

而上面這段程式碼,就是監聽 wheel (滾輪) 事件。一旦使用者滾動了滾輪,它會:

  1. swiper.autoplay.stop():立即停止當前的自動播放計時器。
  2. swiper.autoplay.start():重新啟動一個新的計時器。

這樣一來,自動播放的倒數計時就會從使用者滾輪操作結束後才重新計算,確保使用者有足夠的時間瀏覽他們手動切換到的 slide,提升了互動的流暢度。

Yes

好噠就完成了!我們明天再見吧~


上一篇
不同輪播套件怎麼挑?教你快速選對輪播工具~
下一篇
Swiper 沒有 Tailwind 和 Map 渲染好麻煩?來我幫你寫好了!
系列文
在Vibe Coding 時代一起來做沒有AI感的漂亮網站吧!24
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言