我经常读到,在阅读元素的样式之后更改样式是一种不好的做法,因为它会引发不必要的重排。考虑来自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"
的情况)。
这里我们只是阅读已应用的更改...
不是。分配给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