我是靠谱客的博主 无私石头,最近开发中收集的这篇文章主要介绍react中获取dom元素的高度(table铺满屏幕剩余高度),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

背景

使用antd写了一个table,为了交互上友好;要求如下

  1. 下图红色区域铺满屏幕剩余高度;
  2. table高度不限,有纵向滚动条;
  3. 页面不允许出现纵向滚动条;
    在这里插入图片描述

全量demo地址


知识剖析

  1. 要求1和要求3是同时实现的,只要table铺满屏幕剩余高度即可
  2. 要求2的纵向滚动是通过antd-table的scroll属性实现的,只需要把y的值设置为屏幕剩余高度即可
  3. 那现在的关键就是如何获取屏幕剩余高度了
  4. 屏幕剩余高度=100vh(视窗高度)-header-面包屑-Tab-操作区-间距;如下图
    在这里插入图片描述

编码实战

方案 A 原生js获取高度( Dom)

  • 原理:视窗高度依次减去各模块高度;
  • 优点:简单易懂;
  • 缺点:变量过多,略微繁琐;

核心方法:

export const getResidueHeightByDom = () => {
  const bodyHeight = document.body.offsetHeight; // 网页可见区域高 (包括边线的高)
  const headerHeight = 64; // header高度
  const breadcrumbHeight = 36 + 16 * 2; // 面包屑高度(包括间距)
  const tabHeight = 46 + 16; // tab高度(包括间距)
  const actionHeight = (document.getElementById('action') as HTMLElement).offsetHeight; // 操作区域高度
  const actionMarginBottomHeight = 16; // 操作区域-底部外边距
  const tableHeaderHeight = 55; // table-表头高度
  const paginationHeight = 32 + 16 * 2; // 分页器高度(包括间距)
  const contentBottomPadding = 24; // content区域的底部padding
  const tabContentTopPadding = 24; // tab子元素区域上padding
  const tabContentBottomPadding = 24; // tab子元素区域下padding
  const residueHeight =
    bodyHeight -
    headerHeight -
    breadcrumbHeight -
    tabHeight -
    actionHeight -
    tableHeaderHeight -
    actionMarginBottomHeight -
    paginationHeight -
    contentBottomPadding -
    tabContentTopPadding -
    tabContentBottomPadding;
  window.console.log('Dom-residueHeight', residueHeight);
  return residueHeight;
};

Demo:

demo地址

原生js获取高度

方案 B js 原生(DOMRect)

  • 原理:视窗高度-table 距离顶部距离-底部元素高度-底部间距;

  • 优点:变量较少(方案 A 的优化版);

  • 缺点:只能在页面级别生效;

核心方法:

export const getResidueHeightByDOMRect = () => {
  const bodyHeight = document.body.offsetHeight; // 网页可见区域高 (包括边线的高)
  const tableBodyTop = document
    .getElementsByClassName('ant-table-body')[0]
    .getBoundingClientRect().top; // tableBody距离顶部距离
  const paginationHeight = 32 + 16 * 2; // 分页器高度(包括间距);
  const tabContentBottomPadding = 24; // tab子元素区域下padding
  const contentBottomPadding = 24; // content区域的底部padding
  const residueHeight =
    bodyHeight - tableBodyTop - paginationHeight - contentBottomPadding - tabContentBottomPadding;
  window.console.log('DOMRect-residueHeight', residueHeight);
  return residueHeight;
};

Demo:

demo地址

原生js获取高度

方案 C React-Ref(ref)

  • 原理:视窗高度-table 距离顶部距离-底部元素高度-底部间距;

  • 优点:变量较少(方案 A 的优化版);

  • 缺点:只能在页面级别生效;

核心方法:

export const getResidueHeightByRef = (ele: HTMLElement) => {
  const bodyHeight = document.body.offsetHeight; // 网页可见区域高 (包括边线的高)
  const tableHeaderHeight = 55; // table-表头高度
  const tableBodyTop = ele.getBoundingClientRect().top; // tableBody距离顶部距离
  const paginationHeight = 32 + 16 * 2; // 分页器高度(包括间距);
  const tabContentBottomPadding = 24; // tab子元素区域下padding
  const contentBottomPadding = 24; // content区域的底部padding
  const residueHeight =
    bodyHeight -
    tableHeaderHeight -
    tableBodyTop -
    paginationHeight -
    contentBottomPadding -
    tabContentBottomPadding;
  window.console.log('Ref-residueHeight', residueHeight);
  return residueHeight;
};

Demo:

demo地址


拓展阅读

layout 根据 Sider 的个数动态追加了".ant-layout-has-sider"类名,导致子组件挂载时获取不到正确的布局信息

解决方案: 不依赖组件的状态更新hasSider字段,给 <Layout />组件 添加属性 hasSider

antd-layout 源码

...
const [siders, setSiders] = React.useState<string[]>([]);

  const { prefixCls, className, children, hasSider, tagName: Tag, ...others } = props;
  const classString = classNames(
    prefixCls,
    {
      [`${prefixCls}-has-sider`]: typeof hasSider === 'boolean' ? hasSider : siders.length > 0,
      [`${prefixCls}-rtl`]: direction === 'rtl',
    },
    className,
  );
  ...

参考资料

  • javascript 中获取 dom 元素的高度和宽度

  • DOMRect

  • react-回调 Refs

  • react-hook-hooks FAQ-我该如何测量 DOM 节点?

  • ResizeObserver 接口监听元素内容区域变化

  • antd-layout 源码

最后

以上就是无私石头为你收集整理的react中获取dom元素的高度(table铺满屏幕剩余高度)的全部内容,希望文章能够帮你解决react中获取dom元素的高度(table铺满屏幕剩余高度)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(33)

评论列表共有 0 条评论

立即
投稿
返回
顶部