React.js中如何实现点击图片触发全屏查看效果
React 左右分栏页面点击图片全屏预览实现方案
核心实现逻辑
整个功能无需额外第三方依赖,基于React原生能力即可实现,拆分为3个核心模块:
- 用flex布局实现左右分栏结构,左侧承载文本/业务内容,右侧承载图片展示区
- 通过React state维护全屏预览的开关状态、当前需要预览的图片地址
- 实现fixed定位的全屏遮罩层,绑定点击遮罩关闭、ESC快捷键关闭的交互逻辑
关键实现注意点
- 分栏布局默认按6:4比例分配左右区域宽度,可根据业务需求自行调整,小屏下可通过媒体查询改为上下排布
- 所有可预览的图片添加
cursor: pointer样式,hover时可加轻微缩放动效,给用户明确的可点击提示 - 全屏遮罩层z-index设置为足够大的值(如999),避免被页面其他导航、弹窗元素遮挡
- 绑定键盘ESC关闭事件时,要在组件卸载阶段移除事件监听,避免内存泄漏
- 打开全屏时锁定body滚动,防止背景页面随滚动条滑动;关闭全屏时恢复滚动能力
- 全屏图片设置
max-width: 90%; max-height: 90%+object-fit: contain,保证图片完整展示不溢出视口
完整代码示例
import { useState, useEffect } from 'react'; import './style.css'; export default function SplitLayoutPage() { // 全屏预览开关状态 const [showFullPreview, setShowFullPreview] = useState(false); // 当前全屏展示的图片资源地址 const [activeImg, setActiveImg] = useState(''); // 打开全屏预览 const handleOpenPreview = (imgUrl) => { setActiveImg(imgUrl); setShowFullPreview(true); document.body.style.overflow = 'hidden'; }; // 关闭全屏预览 const handleClosePreview = () => { setShowFullPreview(false); setActiveImg(''); document.body.style.overflow = 'auto'; }; // 监听ESC键关闭全屏 useEffect(() => { const escKeyListener = (e) => { if (e.key === 'Escape' && showFullPreview) handleClosePreview(); }; window.addEventListener('keydown', escKeyListener); return () => window.removeEventListener('keydown', escKeyListener); }, [showFullPreview]); // 示例业务数据,可替换为接口返回的真实内容 const leftContent = "这里替换为左侧区域要展示的文本、表单、卡片、交互组件等任意业务内容"; const rightImgList = [ '/img/demo-1.jpg', '/img/demo-2.jpg', '/img/demo-3.jpg' ]; return ( <div className="split-page-wrap"> {/* 左侧内容区 */} <div className="left-content-block"> {leftContent} </div> {/* 右侧图片区 */} <div className="right-img-block"> {rightImgList.map((img, idx) => ( <img key={idx} src={img} alt={`展示图${idx + 1}`} className="clickable-img" onClick={() => handleOpenPreview(img)} /> ))} </div> {/* 全屏预览层 */} {showFullPreview && ( <div className="fullscreen-mask" onClick={handleClosePreview}> <img src={activeImg} alt="全屏预览" className="fullscreen-img" onClick={e => e.stopPropagation()} /> <button className="preview-close-btn" onClick={handleClosePreview}>×</button> </div> )} </div> ); }
配套样式文件style.css代码:
* { margin: 0; padding: 0; } /* 分栏容器 */ .split-page-wrap { display: flex; width: 100%; min-height: 100vh; } /* 左侧内容区 */ .left-content-block { width: 60%; padding: 24px; box-sizing: border-box; } /* 右侧图片区 */ .right-img-block { width: 40%; padding: 24px; box-sizing: border-box; display: flex; flex-direction: column; gap: 16px; } .clickable-img { width: 100%; border-radius: 8px; cursor: pointer; transition: transform 0.2s ease; } .clickable-img:hover { transform: scale(1.02); } /* 全屏遮罩层 */ .fullscreen-mask { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.9); z-index: 999; display: flex; align-items: center; justify-content: center; } .fullscreen-img { max-width: 90%; max-height: 90%; object-fit: contain; } .preview-close-btn { position: absolute; top: 32px; right: 32px; width: 48px; height: 48px; border-radius: 50%; border: none; background: rgba(255,255,255,0.2); color: #fff; font-size: 32px; cursor: pointer; display: flex; align-items: center; justify-content: center; } .preview-close-btn:hover { background: rgba(255,255,255,0.3); } /* 移动端适配 */ @media (max-width: 768px) { .split-page-wrap { flex-direction: column; } .left-content-block, .right-img-block { width: 100%; } }
可选扩展功能
- 添加上一张/下一张切换按钮,支持全屏状态下连续浏览所有图片
- 增加图片加载中的loading占位效果
- 扩展滚轮缩放、拖拽移动图片的交互能力
内容的提问来源于stack exchange,提问作者sudesh sharma
相关产品推荐
相关产品推荐

