防止遮盖层层下页面滚动,看看Ant Design怎么干的

前言

在平常的开发中,经常会见到遮盖层的身影,比如弹窗基本都是伴随遮盖层的。

正文

这是我们通常使用的方案,就可以了。

js 复制代码
  useEffect(() => {
    if (isShow) {
      document.body.style.overflowY = "hidden";
    } else {
      document.body.style.overflowY = "";
    }
  },[isShow])

现在来看看Ant Design是怎么实现的。原理是一样也是将bodyoverflow属性变为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
}

结语

感兴趣的可以去试试

相关推荐
sunly_几秒前
CSS:跑马灯
前端·css
2301_818732068 分钟前
用layui表单,前端页面的样式正常显示,但是表格内无数据显示(数据库连接和获取数据无问题)——已经解决
java·前端·javascript·前端框架·layui·intellij idea
yqcoder9 分钟前
npm link 作用
前端·npm·node.js
林涧泣15 分钟前
【Uniapp-Vue3】页面和路由API-navigateTo及页面栈getCurrentPages
前端·vue.js·uni-app
Komorebi゛17 分钟前
【uniapp】获取上传视频的md5,适用于APP和H5
前端·javascript·uni-app
林涧泣22 分钟前
【Uniapp-Vue3】动态设置页面导航条的样式
前端·javascript·uni-app
杰九39 分钟前
【全栈】SprintBoot+vue3迷你商城(10)
开发语言·前端·javascript·vue.js·spring boot
Hopebearer_1 小时前
入门 Canvas:Web 绘图的强大工具
前端·javascript·es6·canva可画
m0_748254881 小时前
项目升级Sass版本或升级Element Plus版本遇到的问题
前端·rust·sass
WuwuwuwH_2 小时前
【问题解决】el-upload数据上传成功后不显示成功icon
前端·vue.js·elementui