背景
使用antd写了一个table,为了交互上友好;要求如下
- 下图红色区域铺满屏幕剩余高度;
- table高度不限,有纵向滚动条;
- 页面不允许出现纵向滚动条;
全量demo地址
知识剖析
- 要求1和要求3是同时实现的,只要table铺满屏幕剩余高度即可
- 要求2的纵向滚动是通过antd-table的
scroll
属性实现的,只需要把y
的值设置为屏幕剩余高度即可 - 那现在的关键就是如何获取屏幕剩余高度了
- 屏幕剩余高度=100vh(视窗高度)-header-面包屑-Tab-操作区-间距;如下图
编码实战
方案 A 原生js获取高度( Dom)
- 原理:视窗高度依次减去各模块高度;
- 优点:简单易懂;
- 缺点:变量过多,略微繁琐;
核心方法:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28export 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地址
方案 B js 原生(DOMRect)
-
原理:视窗高度-table 距离顶部距离-底部元素高度-底部间距;
-
优点:变量较少(方案 A 的优化版);
-
缺点:只能在页面级别生效;
核心方法:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14export 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地址
方案 C React-Ref(ref)
-
原理:视窗高度-table 距离顶部距离-底部元素高度-底部间距;
-
优点:变量较少(方案 A 的优化版);
-
缺点:只能在页面级别生效;
核心方法:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19export 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 源码
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14... 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元素内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复