为什么读取DOM测量会触发布局/重排?

问题描述 投票:2回答:1

我经常读到,在阅读元素的样式之后更改样式是一种不好的做法,因为它会引发不必要的重排。考虑来自here的此代码:

错误代码:

elementA.className = "a-style";
var heightA = elementA.offsetHeight;  // layout is needed
elementB.className = "b-style";       // invalidates the layout
var heightB = elementB.offsetHeight;  // layout is needed again

良好代码:

elementA.className = "a-style";
elementB.className = "b-style";
var heightA = elementA.offsetHeight;   // layout is needed and calculated
var heightB = elementB.offsetHeight;   // layout is up-to-date (no work)

我很好奇为什么elementA.offsetHeight会导致布局?在这里,我们只是在读取已应用的更改,而不是真正在应用更改(例如elementA.className = "a-style"的情况)。

javascript html css browser webkit
1个回答
2
投票

这里我们只是阅读已应用的更改...

不是。分配给className意味着浏览器必须重排,但是这并不意味着分配完成后已经有被重排。它可能会等到(在现代浏览器中会等到)它的下一个绘制,直到当前JavaScript代码完成(至少)后才会发生。

但是,当您读取诸如clientHeight之类的计算所得属性时,浏览器必须暂停JavaScript代码并重排页面,以便它可以返回准确的数字。因此,您的“好”代码可以做到这一点:

elementA.className = "a-style";        // marks the layout stale
elementB.className = "b-style";        // marks the layout stale (no change)
var heightA = elementA.offsetHeight;   // triggers reflow
var heightB = elementB.offsetHeight;   // no need for reflow, the layout isn't stale
© www.soinside.com 2019 - 2024. All rights reserved.