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

结语

感兴趣的可以去试试

相关推荐
fanruitian3 小时前
uniapp android开发 测试板本与发行版本
前端·javascript·uni-app
rayufo3 小时前
【工具】列出指定文件夹下所有的目录和文件
开发语言·前端·python
RANCE_atttackkk3 小时前
[Java]实现使用邮箱找回密码的功能
java·开发语言·前端·spring boot·intellij-idea·idea
摘星编程4 小时前
React Native + OpenHarmony:Timeline垂直时间轴
javascript·react native·react.js
2501_944525545 小时前
Flutter for OpenHarmony 个人理财管理App实战 - 支出分析页面
android·开发语言·前端·javascript·flutter
jin1233225 小时前
React Native鸿蒙跨平台完成剧本杀组队详情页面,可以复用桌游、团建、赛事等各类组队详情页开发
javascript·react native·react.js·ecmascript·harmonyos
李白你好5 小时前
Burp Suite插件用于自动检测Web应用程序中的未授权访问漏洞
前端
刘一说6 小时前
Vue 组件不必要的重新渲染问题解析:为什么子组件总在“无故”刷新?
前端·javascript·vue.js
jin1233227 小时前
基于React Native鸿蒙跨平台移动端表单类 CRUD 应用,涵盖地址列表展示、新增/编辑/删除/设为默认等核心操作
react native·react.js·ecmascript·harmonyos
徐同保7 小时前
React useRef 完全指南:在异步回调中访问最新的 props/state引言
前端·javascript·react.js