通过createElement 创建节点获取不到宽度问题

887 阅读2分钟

大家遇到这个问题,首先要搞明白浏览器的渲染过程是什么样子的:

浏览器会将请求回来的html文件进行解析 从而生成DOM树 和 CSS规则树,继续构建成render渲染树
如果构建期间遇到js的话就会执行js(js会阻塞执行), 一旦渲染树构建完成就会进行 重排 之后进行 重绘!

如果这时候js操作DOM后浏览器会进行重排和重绘。将其渲染出来

当你接到一个需求,需要提前知道这些字的宽度,从而根据宽度来做一些操作
例: 直播网站的弹幕 根据字的长度来决定显示不显示提示等....

当你写出

const str = document.createElement('span');
str.innerText = '小白小白,你为什么叫通学,因为没名可起了'

这时候你想要获取他的宽度,你用下面列举的两个方法的话会发现得不到你想要的宽度;
getClientRects: 能直接得到该节点所占的区域
offsetWidth:获取dom content border padding

why?

我的个人理解就是,你虽然创建了这个节点,并没有将他放进页面中经过重排 重绘渲染出来,导致只存在 js 中。所以你需要将他通过 appendChild 来添加进某个节点、或者body中。这时候你就是通过 js 操作 DOM 会引起浏览器的重排 和 重绘将其渲染出来,你就可以获得这个节点的宽度,高度等信息;之后你可以选择创建完干掉还是不干掉那个节点。

上代码

const str = document.createElement('span');
document.body.appendChild(str);
str.innerText = '小白小白,你为什么叫通学,因为没名可起了'
const width = str.getClientRects()[0].width;
document.body.removeChild(str)
console.log('width',width);

欢迎各路大神斧正