react中用JavaScript防止弹出框超出浏览器边界

使用场景

fixed的侧边栏按钮点击弹出的fixed弹框,与该按钮的中点水平对齐;如果会超出屏幕上下边界,则会往里偏移使其不超出边界。react实现。

对齐

侧边栏按钮里放个高度为1的居中的线,然后线里再flex放窗口内容,就能实现窗口与按钮的中点水平居中

right: 90px;
position: absolute;
z-index: 1500;
height: 1px;
cursor: auto;
.arrow-window__inner{
  display: flex;
  align-items: center;
  height: 1px;
}

防止超出边界

这个css实在没法做,得用js来做。

获取数据

js需要获取这些数据:浏览器高度、弹窗内容高度、弹窗位置。通过这些数据计算出弹窗是否超出边界,然后进行偏移把它挪回浏览器里。

浏览器高度:

import { useWindowSize } from "react-use";
let { height: windowHeight } = useWindowSize();

弹窗高度,用ref.current.clientHeight获取。

const popUpRef = useRef(null);
const [innerHeight, setInnerHeight] = useState(-1);

useEffect(() => {
  if (displayOn) {
    if (popUpRef && popUpRef.current) {
      const _popHeight = popUpRef.current.clientHeight;
      setInnerHeight(_popHeight);
    } else {
      console.log('can not Fix WindowPos', popUpRef);
    }
  }
}, [displayOn, innerHeight])

...
<div ref={popUpRef}>...</div>

弹窗位置,用ref.currnet.getBoundingClientRect()。我这里是获取中心点的y坐标。

const [yPos, setYPos] = useState(-1);
useEffect(() => {
  if (displayOn) {
    if (centerRef && centerRef.current) {
      const centerRect = centerRef.current.getBoundingClientRect();
      const { top: _centerTop, y: _centerY } = centerRect;
      setYPos(_centerTop); // IE11没有y,用top代替
    } else {
      console.log('can not get center pos', centerRef);
    }
  }
}, [displayOn, windowHeight])

这样3个数值都拿到了。能再计算一下偏移了

// 调整窗口上下位置,防止超出下边界 参数:整个屏幕高度,窗口高度,窗口中心点y坐标
function FixWindowPos(windowHeight, innerHeight, yPos) {
  if (innerHeight !== -1 && yPos + innerHeight / 2 > windowHeight) {
    const topMove = (-(yPos + innerHeight / 2 - windowHeight) - MIN_PADDING_BOTTOM);
    setPopUpTop(topMove);
  } else if (innerHeight !== -1 && yPos - innerHeight / 2 <= MIN_PADDING_TOP) {
    // 上边界超出了也往下移动
    const topMove = (-(yPos - innerHeight / 2) + MIN_PADDING_TOP);
    // 往下移如果又导致下边距超出了,就不移
    if (!(MIN_PADDING_TOP + innerHeight > windowHeight)) {
      setPopUpTop(topMove);
    }
  }
}

// 计算弹窗位置偏移
useEffect(() => {
  if (displayOn) FixWindowPos(windowHeight, innerHeight, yPos);
}, [displayOn, windowHeight, innerHeight, yPos]);

// style:
transform: translateY(${popUpTop}px);

这样就能把弹窗挪回浏览器视野里了。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值