🎄🎅 節慶特賣:最高 5 折優惠 UI Initiative, Swiper Studio 以及 t0ggles 🎅🎄

Swiper 元素 (WebComponent)

Swiper 網頁元件自 Swiper 版本 9 開始提供。

自訂元素 在所有主要瀏覽器中都受到支援,幾乎每個框架也支援。

安裝

將 Swiper 元素安裝到您的專案中有幾種選項

從 NPM 安裝 & 註冊

我們可以從 NPM 安裝 Swiper

$ npm install swiper

當您從 node modules 導入 Swiper 自訂元素時,我們需要手動註冊它。這應該只執行一次,它會全域註冊 Swiper 自訂元素。

// import function to register Swiper custom elements
import { register } from 'swiper/element/bundle';
// register Swiper custom elements
register();

從 CDN 取得 Swiper 自訂元素

您也可以透過使用 <script> 標籤直接將其添加到網站,從 CDN 安裝。

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

在這種情況下,它將自動註冊,無需呼叫 register()

用法

在我們安裝 Swiper 元素(透過 node modules 並呼叫 register() 或包含腳本標籤)之後,有 2 個網頁元件(自訂元素)可供使用

  • <swiper-container> - 主要 Swiper 元素,您可以在其中定義所有參數
  • <swiper-slide> - Swiper 幻燈片元素
<swiper-container>
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

參數作為屬性

所有 Swiper 參數 都可以在 <swiper-container> 上以 kebab-case 屬性的形式使用,例如

<swiper-container slides-per-view="3" speed="500" loop="true" css-mode="true">
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

所有作為物件傳遞的參數也可以以 [key]-[subkey]="value" 的形式作為屬性傳遞。

例如,這樣的設定

new Swiper('.swiper', {
  slidesPerView: 3,
  grid: {
    rows: 3,
  },
  mousewheel: {
    forceToAxis: true,
  },
});

應該這樣傳遞

<swiper-container
  slides-per-view="3"
  grid-rows="3"
  mousewheel-force-to-axis="true"
>
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

參數作為 Props

在某些更複雜的情況下,當我們有更複雜的參數物件(例如具有中斷點)時,我們可以將所有參數作為 HTMLElement 屬性傳遞。

在這裡,我們需要新增 init="false" 屬性,以防止 Swiper 在我們傳遞所有必要的參數之前進行初始化。

<!-- Add init="false" -->
<swiper-container init="false">
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>
<script>
  // swiper element
  const swiperEl = document.querySelector('swiper-container');

  // swiper parameters
  const swiperParams = {
    slidesPerView: 1,
    breakpoints: {
      640: {
        slidesPerView: 2,
      },
      1024: {
        slidesPerView: 3,
      },
    },
    on: {
      init() {
        // ...
      },
    },
  };

  // now we need to assign all parameters to Swiper element
  Object.assign(swiperEl, swiperParams);

  // and now initialize it
  swiperEl.initialize();
</script>

更新參數

可以透過直接變更 Swiper 元素屬性或 HTMLElement 屬性(如果它是使用 props 初始化)來更新 Swiper 參數;

<swiper-container slides-per-view="1">
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

<button>Update</button>

<script>
  const swiperEl = document.querySelector('swiper-container');
  const buttonEl = document.querySelector('button');

  buttonEl.addEventListener('click', () => {
    // if it was initialized with attributes
    swiperEl.setAttribute('slides-per-view', '3');

    // or if it was initialized with props
    swiperEl.slidesPerView = 3;
  });
</script>

存取 Swiper 實例

初始化的 Swiper 實例可以作為 Swiper HTMLElementswiper 屬性使用

<swiper-container slides-per-view="1">
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

<button>Slide Next</button>

<script>
  const swiperEl = document.querySelector('swiper-container');
  const buttonEl = document.querySelector('button');

  buttonEl.addEventListener('click', () => {
    swiperEl.swiper.slideNext();
  });
</script>

事件

所有 Swiper 事件 都以原生 DOM 事件的形式提供,但名稱為小寫,並帶有 swiper 前綴(可透過 events-prefix 參數設定)。例如,slideChange 變成 swiperslidechange

所有事件處理程式引數都以陣列形式在 event.detail 中傳遞

<swiper-container>
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

<script>
  const swiperEl = document.querySelector('swiper-container');

  swiperEl.addEventListener('swiperprogress', (event) => {
    const [swiper, progress] = event.detail;
  });

  swiperEl.addEventListener('swiperslidechange', (event) => {
    console.log('slide changed');
  });
</script>

也可以使用 events-prefix 屬性/參數為發出的事件名稱加上前綴,以防止與其他程式庫或原生事件衝突

<swiper-container events-prefix="swiper-">
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

<script>
  const swiperEl = document.querySelector('swiper-container');

  swiperEl.addEventListener('swiper-progress', (event) => {
    const [swiper, progress] = event.detail;
  });

  swiperEl.addEventListener('swiper-slidechange', (event) => {
    console.log('slide changed');
  });
</script>

分頁、導覽、捲軸

如果您未在參數中傳遞這些模組元素(例如 scrollbar.elpagination.el),如果指定了模組參數,它將會自動呈現它們

<!-- enable navigation, pagination, scrollbar -->
<swiper-container navigation="true" pagination="true" scrollbar="true">
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

延遲載入

如果您使用延遲載入影像,則需要將延遲預載器元素新增到每個幻燈片。 swiper-slide 元件可以透過新增 lazy="true" 屬性來自動執行此操作

<swiper-container>
  <!-- lazy="true" attribute will automatically render the preloader element -->
  <swiper-slide lazy="true">
    <img src="..." loading="lazy" />
  </swiper-slide>
  <swiper-slide lazy="true">
    <img src="..." loading="lazy" />
  </swiper-slide>
  <swiper-slide lazy="true">
    <img src="..." loading="lazy" />
  </swiper-slide>
  ...
</swiper-container>

虛擬幻燈片

我們有 2 個選項可以在 Swiper 網頁元件中使用虛擬幻燈片。

第一個選項是在 virtual.slides 陣列中傳遞幻燈片,但是它會要求使用元素屬性來初始化 Swiper 元素

<swiper-container init="false"></swiper-container>
<script>
  // swiper element
  const swiperEl = document.querySelector('swiper-container');

  // swiper parameters
  const swiperParams = {
    virtual: {
      // virtual slides
      slides: ['Slide 1', 'Slide 2', 'Slide 3'],
    },
  };

  // assign all parameters to Swiper element
  Object.assign(swiperEl, swiperParams);

  // and now initialize it
  swiperEl.initialize();
</script>

從版本 9 開始,Swiper 虛擬幻燈片可以使用最初在 DOM 中呈現的幻燈片。在初始化時,它會從 DOM 中移除它們,快取,然後重複使用所需的幻燈片

<!-- it is enough to add virtual="true" attribute -->
<swiper-container virtual="true">
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

縮圖

在版本 9 中,thumbs.swiper 參數也接受縮圖 swiper 的 CSS 選取器。因此,為了使兩者都使用 Swiper 元素,我們可以執行下列操作

<!-- main swiper, pass thumbs swiper as CSS selector -->
<swiper-container thumbs-swiper=".my-thumbs"> ... </swiper-container>

<!-- thumbs swiper -->
<swiper-container class="my-thumbs"> ... </swiper-container>

控制器

與縮圖相同,版本 9 中的控制器也接受 CSS 選取器

<swiper-container class="swiper-1" controller-control=".swiper-2">
  ...
</swiper-container>

<swiper-container class="swiper-2" controller-control=".swiper-1">
  ...
</swiper-container>

注入樣式

如果您需要將樣式新增至陰影 DOM 範圍,則可以使用 injectStylesinjectStylesUrls 參數,例如

<swiper-container init="false"> ... </swiper-container>
<script type="module">
  import { register } from 'swiper/element/bundle';

  register();

  const swiperEl = document.querySelector('swiper-container');

  const params = {
    // array with CSS styles
    injectStyles: [
      `
      :host(.red) .swiper-wrapper {
        background-color: red;
      }
      `,
    ],

    // array with CSS urls
    injectStylesUrls: ['path/to/one.css', 'path/to/two.css'],
  };

  Object.assign(swiperEl, params);

  swiperEl.initialize();
</script>

核心版本 & 模組

還有 Swiper 元素的核心版本(沒有額外的模組)。

可以從 node modules 導入

// import function to register Swiper Core custom elements
import { register } from 'swiper/element';
// register Swiper custom elements
register();

為了新增模組,我們需要像往常一樣使用 modules 參數來包含模組腳本,並且我們也需要全域新增模組樣式,並且將模組樣式注入到陰影 DOM 中

<swiper-container init="false"> ... </swiper-container>

<script>
  import { register } from 'swiper/element';
  import { Navigation, Pagination } from 'swiper/modules';

  register();

  const swiperEl = document.querySelector('swiper-container');

  const params = {
    modules: [Navigation, Pagination],
    // inject modules styles to shadow DOM
    injectStylesUrls: [
      'path/to/navigation-element.min.css',
      'path/to/pagination-element.min.css',
    ],
  };

  Object.assign(swiperEl, params);

  swiperEl.initialize();
</script>

以下元素模組樣式匯入可用

  • swiper/element/css/a11y - A11y 模組所需的樣式
  • swiper/element/css/autoplay - 自動播放模組所需的樣式
  • swiper/element/css/controller - 控制器模組所需的樣式
  • swiper/element/css/effect-cards - 卡片效果模組所需的樣式
  • swiper/element/css/effect-coverflow - Coverflow 效果模組所需的樣式
  • swiper/element/css/effect-creative - Creative 效果模組所需的樣式
  • swiper/element/css/effect-cube - Cube 效果模組所需的樣式
  • swiper/element/css/effect-fade - 淡入淡出效果模組所需的樣式
  • swiper/element/css/effect-flip - 翻轉效果模組所需的樣式
  • swiper/element/css/free-mode - 自由模式模組所需的樣式
  • swiper/element/css/grid - 網格模組所需的樣式
  • swiper/element/css/hash-navigation - 雜湊導覽模組所需的樣式
  • swiper/element/css/history - 歷史記錄模組所需的樣式
  • swiper/element/css/keyboard - 鍵盤模組所需的樣式
  • swiper/element/css/manipulation - 操作模組所需的樣式
  • swiper/element/css/mousewheel - 滑鼠滾輪模組所需的樣式
  • swiper/element/css/navigation - 導覽模組所需的樣式
  • swiper/element/css/pagination - 分頁模組所需的樣式
  • swiper/element/css/parallax - 視差模組所需的樣式
  • swiper/element/css/scrollbar - 捲軸模組所需的樣式
  • swiper/element/css/thumbs - 縮圖模組所需的樣式
  • swiper/element/css/virtual - 虛擬模組所需的樣式
  • swiper/element/css/zoom - 縮放模組所需的樣式

插槽

預設情況下,所有 swiper-container 子元素都會呈現為 .swiper-wrapper 元素的子元素。如果您需要在之前或之後新增元素,則有兩個可用的插槽

  • container-start - 將在 .swiper-wrapper 之前呈現
  • container-end - 將在 .swiper-wrapper 之後呈現
<swiper-container>
  <div slot="container-start">Rendered before wrapper</div>
  <div slot="container-end">Rendered after wrapper</div>
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
  ...
</swiper-container>

零件

以下 CSS 零件可用於設定樣式

  • container - <div class="swiper"> 的樣式
  • wrapper - <div class="swiper-wrapper"> 的樣式
  • button-prev - 上一個導覽按鈕 <div class="swiper-button-prev"> 的樣式
  • button-next - 下一個導覽按鈕 <div class="swiper-button-next"> 的樣式
  • pagination - 上一個分頁容器 <div class="swiper-pagination"> 的樣式
    • bullet - 分頁項目符號元素的樣式
    • bullet-active - 使用中分頁項目符號元素的樣式
  • scrollbar - - 捲軸容器 <div class="swiper-scrollbar"> 的樣式

例如

swiper-container::part(bullet-active) {
  background-color: red;
}

註冊參數

自 9.1.0 起,有一個新的全域 window.SwiperElementRegisterParams 函式來註冊不屬於預設 Swiper 參數的新(或額外)參數。如果您將 Swiper 元素與某些擴充 Swiper 參數的自訂外掛搭配使用,則可能需要這樣做。

// register swiper-container HTMLElement props to be treated as Swiper parameters
window.SwiperElementRegisterParams(['foo', 'bar']);

const swiperEl = document.querySelector('swiper-container');

Object.assign(swiperEl, {
  foo: 1,
  bar: 2,
});

swiperEl.initialize();

在 React 中使用

React 尚未完全支援網頁元件(截至版本 18)。因此,使用方法基本上與 HTML 相同

import { useRef, useEffect } from 'react';
import { register } from 'swiper/element/bundle';

register();

export const MyComponent = () => {
  const swiperElRef = useRef(null);

  useEffect(() => {
    // listen for Swiper events using addEventListener
    swiperElRef.current.addEventListener('swiperprogress', (e) => {
      const [swiper, progress] = e.detail;
      console.log(progress);
    });

    swiperElRef.current.addEventListener('swiperslidechange', (e) => {
      console.log('slide changed');
    });
  }, []);

  return (
    <swiper-container
      ref={swiperElRef}
      slides-per-view="3"
      navigation="true"
      pagination="true"
    >
      <swiper-slide>Slide 1</swiper-slide>
      <swiper-slide>Slide 2</swiper-slide>
      <swiper-slide>Slide 3</swiper-slide>
      ...
    </swiper-container>
  );
};

在 Vue 中使用

Vue 完全支援網頁元件,包括將屬性作為 props 傳遞以及監聽自訂事件

<template>
  <swiper-container
    :slides-per-view="3"
    :space-between="spaceBetween"
    :centered-slides="true"
    :pagination="{
      hideOnClick: true
    }"
    :breakpoints="{
      768: {
        slidesPerView: 3,
      },
    }"
    @swiperprogress="onProgress"
    @swiperslidechange="onSlideChange"
  >
    <swiper-slide>Slide 1</swiper-slide>
    <swiper-slide>Slide 2</swiper-slide>
    <swiper-slide>Slide 3</swiper-slide>
  </swiper-container>
</template>

<script>
  import { register } from 'swiper/element/bundle';

  register();

  export default function () {
    setup() {
      const spaceBetween = 10;
      const onProgress = (e) => {
        const [swiper, progress] = e.detail;
        console.log(progress)
      };

      const onSlideChange = (e) => {
        console.log('slide changed')
      }

      return {
        spaceBetween,
        onProgress,
        onSlideChange,
      };
    }
  }
</script>

與 Svelte 的用法

Svelte 完全支援 Web Components,包括將屬性作為 props 傳遞以及監聽自訂事件

<script>
  import { register } from 'swiper/element/bundle';

  register();

  const spaceBetween = 10;
  const onProgress = (e) => {
    const [swiper, progress] = e.detail;
    console.log(progress)
  };
  const onSlideChange = (e) => {
    console.log('slide changed')
  }
</script>

<swiper-container
  slides-per-view={3}
  space-between={spaceBetween}
  centered-slides={true}
  pagination={{
    hideOnClick: true,
  }}
  breakpoints={{
    768: {
      slidesPerView: 3,
    },
  }}
  on:swiperprogress={onProgress}
  on:swiperslidechange={onSlideChange}
>
  <swiper-slide>Slide 1</swiper-slide>
  <swiper-slide>Slide 2</swiper-slide>
  <swiper-slide>Slide 3</swiper-slide>
</swiper-container>

與 Solid 的用法

Solid 完全支援 Web Components,包括將屬性作為 props 傳遞以及監聽自訂事件

import { register } from 'swiper/element/bundle';

register();

export default () => {
  const spaceBetween = 10;
  const onProgress = (e) => {
    const [swiper, progress] = e.detail;
    console.log(progress);
  };
  const onSlideChange = (e) => {
    console.log('slide changed');
  };
  return (
    <swiper-container
      slides-per-view={1}
      space-between={spaceBetween}
      centered-slides={true}
      pagination={{
        hideOnClick: true,
      }}
      breakpoints={{
        768: {
          slidesPerView: 3,
        },
      }}
      onSwiperprogress={onProgress}
      onSwiperslidechange={onSlideChange}
    >
      <swiper-slide>Slide 1</swiper-slide>
      <swiper-slide>Slide 2</swiper-slide>
      <swiper-slide>Slide 3</swiper-slide>
    </swiper-container>
  );
};

下一步是什麼?

如您所見,將 Swiper 整合到您的網站或應用程式中非常容易。所以接下來的步驟是:

  • 前往API 文件以了解更多關於所有 Swiper API 以及如何控制它的資訊。
  • 查看可用的範例
  • 如果您有關於 Swiper 的問題,請在StackOverflowSwiper Discussions 中提問。
  • 如果您發現錯誤,請在 GitHub 上建立 issue。
  • 如果您正在尋求支援,我們為 Swiper Patrons 提供了私人的 Discord 支援聊天室。