动态生成DOM元素的高度及行数获取与计算方法
背景
在开发IM的项目过程中,经常会有出现一些需要计算DOM高度,然后超出若干行隐藏等需求。很多时候,需要计算高度的DOM元素都是动态生成的,我们无法在数据渲染前获取到它的高度。
但是,如果我们需要获取到这段在内存中未渲染的动态文本,也能够通过如下几个方法。
技术方案
根据前端的基本常识,在内存中未渲染的DOM元素是无法获取到高度的,因此我们有两个方向来解决这个难题:
- 通过字数对行数进行估算
- 将元素渲染后进行高度测算
实现方案
以下的实现方案将根据上面所选择的技术方案来进行实现。
通过字数进行估算
方案
此方案无需多言,就是通过字数和每一行能够容下的字的个数进行估算等。在项目最开始时,我采用的就是这个方案。具体实现代码太过简单,因此也不在此添加了。
优点
此方案实现简单,基本不需要任何成本,适用于只有等宽文字的情况下。
缺点
这个方案缺点也比较明显,基本无法用于纯文本之外的任何情况。如果字体为非等宽字体或者存在
\n
之类的换行符或者是
\t
之类的制表符时,估算的准确度也会大大下降。
在DOM渲染后进行操作
方案
顾名思义,此方案就是先不考虑DOM元素行数逻辑,直接将所有的DOM节点全部渲染到页面中,渲染完成后再对进行后续逻辑判断。获取高度后页面行数计算将在后面统一讲解。
优点
此方案通过直接在实际场景的页面上渲染后进行高度计算,因此计算精准,不存在任何偏差。同时,此方案实现起来也较为简单,只需要将业务逻辑执行时间后延,并不需要开发额外的代码。
缺点
该方案缺点也比较明显,由于是先渲染后处理,因此页面DOM元素会出现重绘和重排,导致页面闪动,从而影响用户的体验。
镜像计算
方案
该方案的灵感来自于上一个方案。因为在实际的页面中进行计算能够保证页面高度计算没有任何误差,因此我们需要一个实际的场景,让浏览器来帮助我们进行高度计算。同时,我们又不能在具体的功能页面中先渲染后计算,因此我们可以直接创建一个与实际页面中一模一样的 容器 来进行高度计算。这样我们既能够精确计算,又能够不影响用户体验。
具体实现的代码可以参考如下示例:
export default function getLines(element = 'div', style = {}, html = '') {
let node = document.createElement(element);//创建一个新容器
let length;
each(style, (element, index)=>{
node.style[index] = element;//将传入的style遍历后赋值给新容器
node.innerHTML = html;
document.body.appendChild(node);//需要将新容器挂载到DOM中,浏览器才会进行高度计算
let height = global.getComputedStyle(node).height;
document.body.removeChild(node);//需要将镜像DOM进行移除
if(height.indexOf('px')>0) {