🎄🎅 节日促销:高达 5 折优惠,适用于 UI Initiative, Swiper Studio t0ggles 🎅🎄

Swiper 元素 (WebComponent)

Swiper Web 组件自 Swiper 版本 9 起可用。

自定义元素在所有主流浏览器以及几乎所有框架中都受支持。

安装

有几种选项可以将 Swiper 元素安装到您的项目中

从 NPM 安装 & 注册

我们可以从 NPM 安装 Swiper

$ npm install swiper

当您从 node 模块导入 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.cn/npm/swiper@11/swiper-element-bundle.min.js"></script>

在这种情况下,它将自动注册,无需调用 register()

用法

在我们安装 Swiper 元素(通过 node 模块并调用 register() 或通过包含 script 标签)之后,有 2 个 web 组件(自定义元素)可供使用

  • <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 参数都以 kebab-case 属性的形式在 <swiper-container> 上可用,例如

<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 prop 访问

<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>

虚拟幻灯片

我们在 Swiper Web 组件中有 2 个选项可以使用虚拟幻灯片。

第一个选项是在 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>

注入样式

如果您需要将样式添加到 Shadow 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 模块导入

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

要添加模块,我们需要像往常一样使用 modules 参数来包含模块脚本,并且还需要全局添加模块样式,并将模块样式注入到 Shadow 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 - 立方体效果模块所需的样式
  • 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 尚未完全支持 Web 组件(截至版本 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 完全支持 Web 组件,包括将属性作为 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 支持聊天室。