You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiperJS + React:幻灯片失活时如何停止对应视频播放

Swiper多视频轮播问题修复方案

核心修改点

  • 利用Swiper内置的幻灯片切换回调事件,统一管控所有视频的播放状态,切换时暂停所有非活动幻灯片内的视频,解决声音叠加问题
  • 回调中读取当前活动幻灯片的真实索引(适配loop循环模式),同步更新useState存储的当前视频标题
  • 初始化轮播时自动设置首个活动幻灯片的标题,避免初始状态值为空

关键逻辑说明

  • 开启loop循环模式时,不要直接用返回对象的activeIndex取值,要使用realIndex获取对应原始数组的真实索引,避免循环模式下克隆幻灯片导致索引匹配错误
  • 视频选择器加专属类名限定范围,避免误选中页面其他位置的视频元素
  • 非活动视频仅做暂停处理即可,用户手动点击播放时不受限制

完整修改后代码

import { Navigation, Pagination } from 'swiper'
import { Swiper, SwiperSlide } from 'swiper/react'
import 'swiper/css'
import 'swiper/css/pagination'
import { useState } from 'react'

const slides = [
  {
    videoPath: '/img/case-studies/snacklins/tiktoks/SNACKLINS_TikTok_HotGirlShit',
    title: 'Hot Girl Shit',
  },
  {
    videoPath: '/img/case-studies/snacklins/tiktoks/SNACKLINS_TikTok_HowBizarre',
    title: 'How Bizarre',
  },
  {
    videoPath: '/img/case-studies/snacklins/tiktoks/SNACKLINS_TikTok_NobleQuest',
    title: 'Noble Quest',
  },
]

function CaseStudies_TikTok() {
  const [activeTitle, setActiveTitle] = useState('')
  // 轮播视频专属类名,用于元素选择
  const carouselVideoClass = 'carousel-video'

  // 幻灯片切换统一处理逻辑
  const handleSlideChange = (swiper) => {
    const currentRealIndex = swiper.realIndex
    // 更新当前活动视频标题
    setActiveTitle(slides[currentRealIndex].title)
    // 获取当前轮播下所有视频
    const allVideos = swiper.el.querySelectorAll(`.${carouselVideoClass}`)
    allVideos.forEach((video, index) => {
      // 非当前活动视频暂停
      if (index !== swiper.activeIndex) {
        video.pause()
      } 
      // 如需切换后自动播放当前视频,放开下面注释即可
      // else {
      //   video.play().catch(() => {})
      // }
    })
  }

  function SetSlide({ slide }) {
    return (
      <video
        controls
        muted={false}
        className={`h-full w-auto border-6 border-cream rounded-lg hover:cursor-grab ${carouselVideoClass}`}
      >
        <source src={`${slide.videoPath}.webm`} type='video/webm' />
        <source src={`${slide.videoPath}.mp4`} type='video/mp4' />
      </video>
    )
  }

  const Carousel = () => {
    return (
      <Swiper
        spaceBetween={20}
        slidesPerView={1.25}
        loop
        navigation={{
          nextEl: '.carousel-button-next',
          prevEl: '.carousel-button-prev',
        }}
        pagination={{
          clickable: true,
          el: '.carousel-pagination',
          type: 'fraction',
        }}
        modules={[Navigation, Pagination]}
        // 初始化时设置首个标题
        onSwiper={(swiper) => {
          setActiveTitle(slides[swiper.realIndex].title)
        }}
        // 绑定切换事件
        onSlideChange={handleSlideChange}
      >
        {slides.map((slide, index) => {
          return (
            <SwiperSlide key={index}>
                <SetSlide slide={slide} />
            </SwiperSlide>
          )
        })}
      </Swiper>
    )
  }
  return (
      <>
          <Carousel />
          {/* 展示当前活动视频标题 */}
          <div className="text-center text-cream text-xl mt-2">当前播放:{activeTitle}</div>
          <div className='flex flex-row justify-around text-cream mt-4 text-lg'>
          <button className='carousel-button-prev'>prev</button>
          <div className='text-center carousel-pagination font-italic'></div>
          <button className='carousel-button-next'>next</button>
          </div>
      </>
  )
}
export default CaseStudies_TikTok

可选优化:如果需要切换回之前看过的幻灯片时自动从上次暂停位置继续播放,现有逻辑已经天然支持,因为pause()不会重置视频播放进度;如果需要每次切回都从头播放,在暂停逻辑后加video.currentTime = 0即可。

内容的提问来源于stack exchange,提问作者JordyJordyJordyJordan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 16:36:39