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

结语

感兴趣的可以去试试

相关推荐
CnLiang1 分钟前
React Compiler Plugin
前端·react.js
一只爱吃糖的小羊9 分钟前
React 19 生命周期:从入门到实战的完整指南
前端·react.js
乔伊酱12 分钟前
Bean Searcher 遇“鬼”记:为何我的查询条件偷偷跑进了 HAVING?
java·前端·orm
uu_code00715 分钟前
字节磨皮算法详解
前端
HashTang17 分钟前
【AI 编程实战】第 2 篇:让 AI 成为你的前端架构师 - UniApp + Vue3 项目初始化
前端·vue.js·ai编程
白中白1213825 分钟前
Vue系列-1
前端·javascript·vue.js
dorisrv27 分钟前
Next.js 16 自定义 SVG Icon 组件实现方案 🎨
前端
用户新1 小时前
五万字沥血事件 深度学习 事件 循环 事件传播 异步 脱离新手区 成为事件达人
前端·javascript·事件·event loop
w2sfot1 小时前
JS代码压缩
前端·javascript·html
码途潇潇1 小时前
从组件点击事件到业务统一入口:一次前端操作链的完整解耦实践
前端