防止遮盖层层下页面滚动,看看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
}

结语

感兴趣的可以去试试

相关推荐
Juchecar1 分钟前
Vue 3 单页应用Router路由跳转示例
前端
这人是玩数学的3 分钟前
在 Cursor 中规范化生成 UI 稿实践
前端·ai编程·cursor
UncleKyrie4 分钟前
🎨 市面上主流 Figma to Code MCP 对比
前端
南半球与北海道#17 分钟前
前端引入vue-super-flow流程图插件
前端·vue.js·流程图
然我24 分钟前
React 16.8:不止 Hooks 那么简单,这才是真正的划时代更新 🚀
前端·react.js·前端框架
小高00737 分钟前
📈前端图片压缩实战:体积直降 80%,LCP 提升 2 倍
前端·javascript·面试
OEC小胖胖40 分钟前
【React Hooks】封装的艺术:如何编写高质量的 React 自-定义 Hooks
前端·react.js·前端框架·web
BillKu1 小时前
vue3+element-plus 输入框el-input设置背景颜色和字体颜色,样式效果等同于不可编辑的效果
前端·javascript·vue.js
惊悚的毛毛虫1 小时前
掘金免广告?不想看理财交流圈?不想看exp+8?
前端
springfe01011 小时前
vue3组件 - 大文件上传
前端·vue.js