代码之家  ›  专栏  ›  技术社区  ›  darKnight

为什么读取DOM度量会触发布局/回流?

  •  2
  • darKnight  · 技术社区  · 5 年前

    我经常读到,在阅读元素的样式之后更改样式是一种不好的做法,因为它会触发不必要的回流。考虑以下代码 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" ).

    1 回复  |  直到 5 年前
        1
  •  2
  •   T.J. Crowder    5 年前

    这里我们只是阅读已经应用的变化。。。

    不是真的。分配给 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