滑动元素(WebComponent)

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

¥Swiper web components are available since Swiper version 9.

自定义元素是 supported in all major browsers 以及几乎所有 framework 元素都支持。

¥Custom elements are supported in all major browsers and by almost every framework.

安装

¥Installation

如何在项目中安装 Swiper 元素有以下几种方法:

¥There are few options on how to install Swiper Element into your project:

从 NPM 安装并注册

¥Install & Register from NPM

我们可以从 NPM 安装 Swiper

¥We can install Swiper from NPM

$ npm install swiper

从 Node 模块导入 Swiper 自定义元素时,我们需要手动注册它。它应该只执行一次,它会全局注册 Swiper 自定义元素。

¥When you import Swiper custom elements from node modules, we need to manually register it. It should be done only once and it registers Swiper custom elements globally.

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

来自 CDN 的 Swiper 自定义元素

¥Swiper Custom Elements from CDN

你也可以通过 CDN 安装,直接将其添加到带有 <script> 标签的网站:

¥You can also install it from CDN by directly adding it to the website with <script> tag:

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

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

¥In this case, it will be automatically registered, no need to call register()

用法

¥Usage

安装 Swiper 元素后(通过 Node 模块调用 register() 或包含 script 标签),有 2 个 Web 组件(自定义元素)可供使用:

¥After we install Swiper Element (via node modules and calling register() or by including a script tag), there are 2 web components (custom elements) available for usage:

  • <swiper-container> - 定义所有参数的主 Swiper 元素

    ¥<swiper-container> - main Swiper element where you define all parameters

  • <swiper-slide> - 滑动条元素

    ¥<swiper-slide> - Swiper slide element

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

作为属性的参数

¥Parameters As Attributes

所有 Swiper parameters 属性在 <swiper-container> 上都以 kebab-case 属性的形式提供,例如:

¥All Swiper parameters are available in a form of kebab-case attributes on <swiper-container>, for example:

<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" 属性的形式传递。

¥All parameters that are passed as objects also can be passed as attributes in a form of [key]-[subkey]="value".

例如,这样的配置:

¥For example, such configuration:

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

应按以下方式传递:

¥should be passed in this way:

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

作为属性的参数

¥Parameters As Props

在某些更复杂的情况下,当我们有更复杂的参数对象(例如断点)时,我们可以将所有参数作为 HTMLElement 属性传递。

¥In some more complex cases when we have more complex parameters objects (like with breakpoints), we can pass all parameters as HTMLElement properties.

在这里,我们需要添加 init="false" 属性,以防止 Swiper 在传递所有必需参数之前进行初始化。

¥Here, we need to add init="false" attribute to prevent Swiper from initialization until we pass all required parameters.

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

更新参数

¥Updating Parameters

可以通过直接更改 Swiper 元素属性或 HTMLElement 属性(如果使用 props 初始化)来更新 Swiper 参数;

¥Swiper parameters can be updated by directly changing Swiper element attributes or HTMLElement properties (if it was initialized with props);

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

¥Access To Swiper Instance

已初始化的 Swiper 实例可作为 Swiper HTMLElementswiper 属性使用:

¥Initialized Swiper instance is available as swiper prop of Swiper's HTMLElement:

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

事件

¥Events

所有 Swiper events 均可用作原生 DOM 事件 but with lowercase namesswiper 前缀(可通过 events-prefix 参数配置)。例如:slideChange 变为 swiperslidechange

¥All Swiper events are available as native DOM events but with lowercase names and swiper prefix (configurable via events-prefix parameter). E.g. slideChange becomes swiperslidechange.

所有事件处理程序参数在 event.detail 中都以数组形式传递:

¥All event handler arguments are passed as array in 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 属性/参数为发出的事件名称添加前缀,以防止与其他库或原生事件冲突:

¥It is also possible to prefix emitted events names to prevent clashing with other libs or native events using events-prefix attribute/parameter:

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

分页、导航、滚动条

¥Pagination, Navigation, Scrollbar

如果你没有在参数中传递这些模块元素(例如 scrollbar.elpagination.el),如果指定了模块参数,它将自动渲染它们:

¥If you don't pass these modules elements in parameters (e.g. scrollbar.el, pagination.el), it will render them automatically, if module parameter is specified:

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

延迟加载

¥Lazy

如果你使用延迟加载图片,则需要在每张幻灯片中添加延迟加载预加载器元素。swiper-slide 组件可以通过添加 lazy="true" 属性自动执行此操作:

¥If you use lazy loading images, it requires the lazy preloader element to be added to the each slide. swiper-slide component can do this automatically by adding lazy="true" attribute:

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

虚拟幻灯片

¥Virtual Slides

在 Swiper Web 组件中使用虚拟幻灯片有两种方式。

¥We have 2 options to use Virtual slides in Swiper web components.

第一种方案是将幻灯片传入 virtual.slides 数组,但这需要使用元素属性来初始化 Swiper 元素:

¥First option is to pass slides in virtual.slides array, but it will require to use element properties to initialize Swiper element:

<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 中移除这些元素,进行缓存,然后重新使用需要的元素:

¥Since version 9, Swiper virtual slides can work with slides originally rendered in DOM. On initialize it will remove them from DOM, cache and then re-use the ones which are required:

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

缩略图

¥Thumbs

在版本 9 中,thumbs.swiper 参数也接受缩略图滑动条的 CSS 选择器。要使用 Swiper 元素同时实现这两种功能,我们可以使用以下代码:

¥In version 9 thumbs.swiper parameter also accepts CSS Selector of the thumbs swiper. So to make both with Swiper elements we can use the following:

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

控制器

¥Controller

与缩略图相同,版本 9 中的控制器也接受 CSS 选择器:

¥Same as with Thumbs, Controller in version 9 also accepts CSS Selector:

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

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

注入样式

¥Injecting Styles

如果你需要将样式添加到影子 DOM 作用域,则可以使用 injectStylesinjectStylesUrls 参数,例如:

¥If you need to add styles to shadow DOM scope, you can use injectStyles or injectStylesUrls parameters, e.g.:

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

核心版本和模块

¥Core Version & Modules

Swiper 元素还有核心版本(无需额外模块)。

¥There is also Core version of Swiper element available (without additional modules).

它可以从 Node 模块导入:

¥It can be imported from node modules:

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

要添加模块,我们需要像往常一样使用 modules 参数来包含模块脚本,同时还需要全局添加模块样式,并将模块样式注入到影子 DOM。

¥To add modules, we need to use modules parameter as usual to include modules scripts, and we also need to add modules styles globally and also inject modules styles to the 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>

可导入以下元素模块样式:

¥There are following element module styles imports available:

  • swiper/element/css/a11y - A11y 模块所需样式

    ¥swiper/element/css/a11y - styles required for A11y module

  • swiper/element/css/autoplay - 自动播放模块所需样式

    ¥swiper/element/css/autoplay - styles required for Autoplay module

  • swiper/element/css/controller - 控制器模块所需样式

    ¥swiper/element/css/controller - styles required for Controller module

  • swiper/element/css/effect-cards - 卡片效果模块所需样式

    ¥swiper/element/css/effect-cards - styles required for Cards Effect module

  • swiper/element/css/effect-coverflow - Coverflow 效果模块所需样式

    ¥swiper/element/css/effect-coverflow - styles required for Coverflow Effect module

  • swiper/element/css/effect-creative - 创意效果模块所需样式

    ¥swiper/element/css/effect-creative - styles required for Creative Effect module

  • swiper/element/css/effect-cube - 立方体效果模块所需样式

    ¥swiper/element/css/effect-cube - styles required for Cube Effect module

  • swiper/element/css/effect-fade - 所需样式淡入淡出效果模块

    ¥swiper/element/css/effect-fade - styles required for Fade Effect module

  • swiper/element/css/effect-flip - 翻转效果模块所需样式

    ¥swiper/element/css/effect-flip - styles required for Flip Effect module

  • swiper/element/css/free-mode - 自由模式模块所需样式

    ¥swiper/element/css/free-mode - styles required for Free Mode module

  • swiper/element/css/grid - 网格模块所需样式

    ¥swiper/element/css/grid - styles required for Grid module

  • swiper/element/css/hash-navigation - 哈希导航模块所需样式

    ¥swiper/element/css/hash-navigation - styles required for Hash Navigation module

  • swiper/element/css/history - 历史记录模块所需样式

    ¥swiper/element/css/history - styles required for History module

  • swiper/element/css/keyboard - 键盘模块所需样式

    ¥swiper/element/css/keyboard - styles required for Keyboard module

  • swiper/element/css/manipulation - 操作模块所需样式

    ¥swiper/element/css/manipulation - styles required for Manipulation module

  • swiper/element/css/mousewheel - 鼠标滚轮模块所需样式

    ¥swiper/element/css/mousewheel - styles required for Mousewheel module

  • swiper/element/css/navigation - 导航模块所需样式

    ¥swiper/element/css/navigation - styles required for Navigation module

  • swiper/element/css/pagination - 分页模块所需样式

    ¥swiper/element/css/pagination - styles required for Pagination module

  • swiper/element/css/parallax - 视差模块所需样式

    ¥swiper/element/css/parallax - styles required for Parallax module

  • swiper/element/css/scrollbar - 滚动条模块所需样式

    ¥swiper/element/css/scrollbar - styles required for Scrollbar module

  • swiper/element/css/thumbs - 缩略图模块所需样式

    ¥swiper/element/css/thumbs - styles required for Thumbs module

  • swiper/element/css/virtual - 虚拟模块所需样式

    ¥swiper/element/css/virtual - styles required for Virtual module

  • swiper/element/css/zoom - 缩放模块所需样式

    ¥swiper/element/css/zoom - styles required for Zoom module

插槽

¥Slots

默认情况下,所有 swiper-container 子元素都会渲染为 .swiper-wrapper 元素的子元素。如果你需要在前面或后面添加元素,有两个可用插槽:

¥By default all swiper-container children are rendered as children of .swiper-wrapper element. If you need to add elements before or after there are two slots available:

  • container-start - 将在 .swiper-wrapper 之前渲染

    ¥container-start - will be rendered before .swiper-wrapper

  • container-end - 将在 .swiper-wrapper 之后渲染

    ¥container-end - will be rendered after .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>

部分

¥Parts

可用于样式的 CSS 部分如下:

¥There are following CSS parts are available for styling:

  • container - <div class="swiper"> 的样式

    ¥container - styles for <div class="swiper">

  • wrapper - <div class="swiper-wrapper"> 的样式

    ¥wrapper - styles for <div class="swiper-wrapper">

  • button-prev - 上一个导航按钮 <div class="swiper-button-prev"> 的样式

    ¥button-prev - styles for prev Navigation button <div class="swiper-button-prev">

  • button-next - 下一个导航按钮 <div class="swiper-button-next"> 的样式

    ¥button-next - styles for next Navigation button <div class="swiper-button-next">

  • pagination - 上一个分页容器 <div class="swiper-pagination"> 的样式

    ¥pagination - styles for prev Pagination container <div class="swiper-pagination">

    • bullet - 分页项目符号元素的样式

      ¥bullet - styles for Pagination bullet element

    • bullet-active - 活动分页项目符号元素的样式

      ¥bullet-active - styles for active Pagination bullet element

  • scrollbar - * 滚动条容器 <div class="swiper-scrollbar"> 的样式

    ¥scrollbar - - styles for Scrollbar container <div class="swiper-scrollbar">

例如:

¥For example:

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

注册参数

¥Register Parameters

自 9.1.0 版本起,有一个新的全局 window.SwiperElementRegisterParams 函数用于注册不属于 Swiper 默认参数的新(或额外)参数。如果你将 Swiper 元素与一些扩展 Swiper 参数的自定义插件一起使用,则可能需要这样做。

¥Since 9.1.0 there is a new global window.SwiperElementRegisterParams function to register new (or extra) params that are not part of default Swiper parameters. This may be required if you use Swiper element with some custom plugins which extend Swiper parameters.

// 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 一起使用

¥Usage with React

React 尚未完全支持 Web 组件(截至版本 18)。用法与 HTML 基本相同:

¥React doesn't fully supports web components yet (as for version 18). So the usage is basically the same as in 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 一起使用

¥Usage with Vue

Vue 完全支持 Web 组件,包括将属性作为 props 传递以及监听自定义事件:

¥Vue has full support for web components, including passing attributes as props and listening for custom events:

<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 一起使用

¥Usage with Svelte

Svelte 完全支持 Web 组件,包括将属性作为 props 传递以及监听自定义事件:

¥Svelte has full support for web components, including passing attributes as props and listening for custom events:

<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 一起使用

¥Usage with Solid

Solid 完全支持 Web 组件,包括将属性作为 props 传递以及监听自定义事件:

¥Solid has full support for web components, including passing attributes as props and listening for custom events:

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>
  );
};

下一步?

¥What next?

正如你所见,将 Swiper 集成到你的网站或应用中非常容易。接下来的步骤如下:

¥As you see it is really easy to integrate Swiper into your website or app. So here are your next steps: