【问题标题】:Will changing the width of an element cause a reflow after setting visibility: hidden for it?设置可见性后更改元素的宽度是否会导致重排:隐藏?
【发布时间】:2023-03-12 18:56:01
【问题描述】:
以这段代码sn-ps为例:
const div = document.querySelector('#div')
div.style.visibility = "hidden"
div.style.width = "200px"
div.style.visibility = "visible"
div {
width: 100px;
height: 100px;
background-color: gray;
}
<div id="div"></div>
第一次重绘发生在设置visibility:hidden 时,第二次发生在设置visibility: visible 时。但是在这 2 次重绘之间设置width: 200px 会导致重排吗?
在我看来,元素设置visibility:hidden 仍然占据页面空间并且不会从布局树(渲染树)中消失,所以这里会发生回流。但我不确定如何证明这一点。
【问题讨论】:
标签:
browser
repaint
reflow
【解决方案1】:
第一次重绘发生在设置visibility:hidden 时,第二次发生在设置visibility: visible 时。
不,第一次也是唯一一次重绘将在很久之后发生。 (可能不到 16 毫秒,但对我们来说是很长的时间)
重绘仅发生在事件循环的更新渲染阶段,它本身仅在监视器发送 VSync 信号时发生(在 60Hz 监视器上每秒 60 次)。
在这里,您正在同步更改元素的样式,在第一次绘制之前,所以第一个 div.style.visibility = "hidden" 只是被忽略了,绘制者永远不会看到那个状态,当它开始时,它只会看到最后的 visibility = "visible"状态。
但是在这 2 次重绘之间设置 width: 200px 会导致重排吗?
不,设置样式的 height 属性不会触发重排。通常,getter 会触发重排,因为只有 getter 需要更新框位置。
所以如果你有一个像document.body.offsetWidth 这样的行而不是这个高度设置,那么你就会强制回流。
您可以找到大多数触发器的列表here,您可以阅读更多关于此主题的内容here。