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

结语

感兴趣的可以去试试

相关推荐
咖啡の猫26 分钟前
Vue基本路由
前端·vue.js·状态模式
青衫码上行28 分钟前
【Java Web学习 | 第七篇】JavaScript(1) 基础知识1
java·开发语言·前端·javascript·学习
咖啡の猫29 分钟前
Vue编程式路由导航
前端·javascript·vue.js
夏鹏今天学习了吗5 小时前
【性能优化】前端高性能优化策略
前端·性能优化
weixin_427771618 小时前
css font-size 的妙用
前端·css
凤凰战士芭比Q9 小时前
web中间件——Nginx
前端·nginx·中间件
一 乐9 小时前
点餐|智能点餐系统|基于java+ Springboot的动端的点餐系统小程序(源码+数据库+文档)
java·前端·数据库·vue.js·spring boot·小程序·论文
bitbitDown10 小时前
从零打造一个 Vite 脚手架工具:比你想象的简单多了
前端·javascript·面试
liangshanbo121510 小时前
CSS 数学函数完全指南:从基础计算到高级动画
前端·css
码上成长11 小时前
GraphQL:让前端自己决定要什么数据
前端·后端·graphql