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

NextJS 14中Swiper轮播视频占位符显示但视频不显示的解决方法

解决方案

问题核心是绝对定位元素的层级冲突,以及缺少视频加载完成后隐藏占位符的逻辑,按以下步骤修复:

1. 基础修复:解决占位图遮挡视频问题

给视频设置更高层级,同时监听视频加载事件,加载完成后隐藏占位图:

'use client'; // 必须添加,因为要使用客户端事件监听

import { useState } from 'react';
import Image from 'next/image';
import { SwiperSlide } from 'swiper/react';

export default function VideoSlide() {
  const [videoLoaded, setVideoLoaded] = useState(false);

  return (
    <SwiperSlide>
      <div className="relative w-full h-full">
        {/* 占位图:视频加载完成后自动隐藏 */}
        {!videoLoaded && (
          <Image 
            src='/placeholder-image.png' 
            fill 
            alt='placeholder image'
            className="object-cover rounded-lg"
          />
        )}
        
        <video
          id="background-video"
          preload="auto"
          autoPlay
          loop
          muted
          playsInline
          className="w-full h-full object-cover rounded-lg z-10"
          onLoadedData={() => setVideoLoaded(true)}
        >
          <source src="/SlideNew_1.webm" type="video/webm" />
          Your browser does not support the video tag.
        </video>
      </div>
    </SwiperSlide>
  );
}

2. 进阶优化:多视频轮播性能优化

如果轮播包含多个视频,避免一次性加载所有视频浪费资源,结合Swiper的激活状态控制视频预加载:

'use client';

import { useState } from 'react';
import Image from 'next/image';
import { Swiper, SwiperSlide } from 'swiper/react';
import { useSwiper } from 'swiper/react';

export default function VideoCarousel() {
  const swiper = useSwiper();
  const [loadedVideos, setLoadedVideos] = useState([]);

  const markVideoLoaded = (index) => {
    setLoadedVideos(prev => [...prev, index]);
  };

  return (
    <Swiper>
      {[
        { videoSrc: "/SlideNew_1.webm", placeholderSrc: "/placeholder-image.png" },
        { videoSrc: "/SlideNew_2.webm", placeholderSrc: "/placeholder2.png" },
        { videoSrc: "/SlideNew_3.webm", placeholderSrc: "/placeholder3.png" }
      ].map((item, index) => (
        <SwiperSlide key={index}>
          <div className="relative w-full h-full">
            {!loadedVideos.includes(index) && (
              <Image 
                src={item.placeholderSrc} 
                fill 
                alt={`轮播占位图 ${index+1}`}
                className="object-cover rounded-lg"
              />
            )}
            <video
              preload={swiper.activeIndex === index ? "auto" : "none"}
              autoPlay={swiper.activeIndex === index}
              loop
              muted
              playsInline
              className="w-full h-full object-cover rounded-lg z-10"
              onLoadedData={() => markVideoLoaded(index)}
            >
              <source src={item.videoSrc} type="video/webm" />
              Your browser does not support the video tag.
            </video>
          </div>
        </SwiperSlide>
      ))}
    </Swiper>
  );
}

关键说明

  • 用z-10确保视频始终在占位图上方,避免被遮挡。
  • 通过useState跟踪视频加载状态,加载完成后自动移除占位图。
  • 结合Swiper的激活状态控制视频预加载和自动播放,减少初始加载压力。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 15:02:24