React 全屏问题解决方案
1、全屏下弹窗被遮挡的问题
参考:https://www.jianshu.com/p/b22d1ad9533e
原因: 需要全屏的节点部分被传入 screenfull 中,弹窗的层级永远低于全屏,所以被遮挡。
解决方法:
方式1:把整个 body 全屏,真正需要全屏的内容通过样式处理成全屏的样子。这样既可以利用全屏的ESC和自带的退出按钮,又不会存在遮挡弹窗的问题。
方式2:直接iframe嵌入,不会有遮挡问题,但加载会慢点
代码如下
const TestFullScreen: React.FC<Props> = props => {
const reportContent = useRef<HTMLIFrameElement>(null);
const [isFullscreen, setIsFullscreen] = useState(false);
const fullScreen = () => {
if (!document.fullscreenElement) {
setIsFullscreen(false);
}
};
useEffect(() => {
// 监听全屏事件
document.addEventListener('fullscreenchange', fullScreen);
return () => {
document.removeEventListener('fullscreenchange', fullScreen);
};
}, []);
const onFullScreenClick = () => {
// 把body全屏: 解决全屏下弹窗被遮挡的问题
document.querySelector('body')?.requestFullscreen();
// 需要全屏的内容通过样式处理
setIsFullscreen(true);
};
return (
<div className='test-fullscreen'>
<button onClick={onFullScreenClick}>全屏测试</button>
<div
// 全屏时,通过fixed 铺满全屏
className={
isFullscreen
? 'fixed z-[100] top-0 left-0 w-screen h-screen'
: 'h-full'
}
ref={reportContent}
>
{/* 有孩子节点就直接渲染,没有就iframe嵌入url */}
{props?.children ? props.children : <iframe url={url} />}
</div>
</div>
);
};
2、退出后的元素的宽高还是全屏时的宽高
在退出全屏时,重新设置宽高
const fullScreen = () => {
if (!document.fullscreenElement) {
setIsFullscreen(false);
// 当没有children时,为iframe嵌入,不会有这个问题,不需要处理
if (reportContent.current && props?.children) {
reportContent.current.style.width = '100%';
reportContent.current.style.height = 'calc(100% - 40px)';
}
}
};