React.js中点击Swiper图片或全屏图标如何实现幻灯片全屏预览
实现方案
方案1:基于现有Swiper 6.5.1改造(无需新增依赖)
改造步骤
- 新增2个状态变量:控制全屏模态框显隐的
isFullscreen、记录当前激活轮播项索引的activeSlideIndex - 给现有主轮播图、缩略图绑定点击事件,点击时触发全屏开启,同步当前激活的轮播索引;可自行添加全屏图标按钮作为额外触发入口
- 新增全屏模态框DOM结构,仅在
isFullscreen为true时渲染,内部复用Swiper主图+缩略图的逻辑,默认定位到当前激活的轮播项,同时添加关闭按钮、ESC键关闭的适配 - 补充全屏场景下的样式,让轮播容器占满整个视口,缩略图固定在底部展示
修改后代码
App.js
import React, { useState, useEffect } from 'react'; import { Swiper, SwiperSlide } from 'swiper/react'; import SwiperCore, { Navigation, Pagination, Controller, Thumbs } from 'swiper'; import 'swiper/swiper-bundle.css'; import './styles.css'; SwiperCore.use([Navigation, Pagination, Controller, Thumbs]); function App() { const [thumbsSwiper, setThumbsSwiper] = useState(null); const [controlledSwiper, setControlledSwiper] = useState(null); // 新增状态 const [isFullscreen, setIsFullscreen] = useState(false); const [activeSlideIndex, setActiveSlideIndex] = useState(0); const [fullscreenThumbs, setFullscreenThumbs] = useState(null); const slides = []; for (let i = 0; i < 5; i += 1) { slides.push( <SwiperSlide key={`slide-${i}`} tag="li"> <img src={`http://localhost:3000/logo512.png`} style={{ listStyle: 'none', cursor: 'pointer' }} alt={`Slide ${i}`} onClick={() => { setActiveSlideIndex(i); setIsFullscreen(true); }} /> </SwiperSlide> ); } const thumbs = []; for (let i = 0; i < 5; i += 1) { thumbs.push( <SwiperSlide key={`thumb-${i}`} tag="li" style={{ listStyle: 'none', cursor: 'pointer' }}> <img src={`http://localhost:3000/logo192.png`} alt={`Thumbnail ${i}`} onClick={() => { setActiveSlideIndex(i); setIsFullscreen(true); }} ></img> </SwiperSlide> ); } // ESC键关闭全屏 useEffect(() => { const handleEsc = (e) => { if (e.keyCode === 27) setIsFullscreen(false); }; if (isFullscreen) { document.addEventListener('keydown', handleEsc); // 禁止背景滚动 document.body.style.overflow = 'hidden'; } return () => { document.removeEventListener('keydown', handleEsc); document.body.style.overflow = 'auto'; }; }, [isFullscreen]); return ( <React.Fragment> {/* 原有普通轮播 */} <div style={{ position: 'relative' }}> <button className="fullscreen-trigger" onClick={() => setIsFullscreen(true)} style={{ position: 'absolute', top: 10, right: 10, zIndex: 10, cursor: 'pointer' }} > [] </button> <Swiper id="main" thumbs={{ swiper: thumbsSwiper }} controller={{ control: controlledSwiper }} tag="section" wrapperTag="ul" navigation pagination spaceBetween={0} slidesPerView={1} initialSlide={activeSlideIndex} onInit={(swiper) => console.log('Swiper initialized!', swiper)} onSlideChange={(swiper) => { console.log('Slide index changed to: ', swiper.activeIndex); setActiveSlideIndex(swiper.activeIndex); }} onReachEnd={() => console.log('Swiper end reached')} > {slides} </Swiper> <Swiper id="thumbs" spaceBetween={5} slidesPerView={3} onSwiper={setThumbsSwiper} > {thumbs} </Swiper> </div> {/* 全屏模态框 */} {isFullscreen && ( <div className="fullscreen-modal"> <button className="fullscreen-close" onClick={() => setIsFullscreen(false)} style={{ position: 'absolute', top: 20, right: 20, zIndex: 100, color: '#fff', fontSize: 24, background: 'none', border: 'none', cursor: 'pointer' }} > × </button> <Swiper id="fullscreen-main" thumbs={{ swiper: fullscreenThumbs }} tag="section" wrapperTag="ul" navigation spaceBetween={0} slidesPerView={1} initialSlide={activeSlideIndex} onSlideChange={(swiper) => setActiveSlideIndex(swiper.activeIndex)} > {slides} </Swiper> <Swiper id="fullscreen-thumbs" spaceBetween={5} slidesPerView={5} onSwiper={setFullscreenThumbs} style={{ position: 'absolute', bottom: 20, left: '50%', transform: 'translateX(-50%)', width: '80%' }} > {thumbs} </Swiper> </div> )} </React.Fragment> ); } export default App;
styles.css新增内容
/* 原有样式保留,新增以下内容 */ .fullscreen-modal { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; background: rgba(0,0,0,0.9); z-index: 9999; } #fullscreen-main { width: 100%; height: 85vh; } #fullscreen-main img { width: 100%; height: 100%; object-fit: contain; } #fullscreen-thumbs .swiper-slide { opacity: 0.6; } #fullscreen-thumbs .swiper-slide-thumb-active { opacity: 1; border: 2px solid #fff; }
方案2:使用第三方组件快速实现
如果不需要自定义复杂逻辑,可以直接使用npm平台的react-image-gallery组件,原生支持带缩略图的全屏预览能力,只需传入图片数组配置即可快速实现需求。
内容的提问来源于stack exchange,提问作者shivu
相关产品推荐
相关产品推荐

