前言
在平常的开发中,经常会见到遮盖层的身影,比如弹窗基本都是伴随遮盖层的。
正文
这是我们通常使用的方案,就可以了。
js
useEffect(() => {
if (isShow) {
document.body.style.overflowY = "hidden";
} else {
document.body.style.overflowY = "";
}
},[isShow])
现在来看看Ant Design
是怎么实现的。原理是一样也是将body
的overflow
属性变为hidden
,只是实现的方式不一样。
实现方式:当遮盖层出现时,在head
标签下加入style
标签,内容为如下图;当遮盖层消失时,又将创建的style
标签去除。style
标签里的内容会根据实际情况变化,当页面没有出现滚动条时,就不会有width
的设置,设置width
是为了防止在overflow
属性变为hidden
时页面左右晃动。
实现一个遮盖层
知道实现方式和原理后,自己实现一个就简单了,下面只是一个大概的例子
tsx
import { useState, useEffect, useRef, useMemo, useCallback } from 'react'
import { FrameSty } from './style'
interface MaskingLayerProps {
isShow: boolean,
children: React.ReactNode
}
export default function MaskingLayer(props: MaskingLayerProps) {
const { children, isShow } = props;
/** 是否第一次使用过*/
const isFirstShow = useRef(false);
const styleLabel = useRef<any>(null);
//页面宽度和页面实际使用宽度的差值
const screenDifference = useRef(0)
useEffect(() => {
if (isShow) {
isFirstShow.current = true;
const { clientWidth } = window.document.documentElement;
screenDifference.current = window.innerWidth - clientWidth
styleLabel.current = document.createElement('style');
styleLabel.current.innerHTML = `
html body{
overflow-Y:hidden;
${screenDifference.current > 0 ? `width:calc(100% - ${screenDifference.current}px)` : ''}
}
`
document.head.append(styleLabel.current);
} else {
if (isFirstShow.current) {
document.head.removeChild(styleLabel.current);
}
}
}, [isShow])
return (
<>
{
isShow && <FrameSty>
{children}
</FrameSty>
}
</>
)
}
ts
import styled from "styled-components";
const FrameSty = styled.div`
position: fixed;
left:0;
top:0;
height: 100vh;
width: 100vw;
background-color: rgba(0, 0, 0, 0.2);
overflow: hidden;
z-index: 99;
box-sizing: border-box;
`
export {
FrameSty
}
结语
感兴趣的可以去试试