为啥我在更改和检索元素位置时看不到布局/重排被触发?
Posted
技术标签:
【中文标题】为啥我在更改和检索元素位置时看不到布局/重排被触发?【英文标题】:Why don't I see layout/reflow being triggered when changing and retrieving element positions?为什么我在更改和检索元素位置时看不到布局/重排被触发? 【发布时间】:2021-10-21 11:10:06 【问题描述】:我一直在尝试详细了解何时使用 Chrome 开发工具触发布局/重排。我在 JSFiddle 中设置了这个简单的示例,我在 for 循环中一次更改一组 div 的“左”位置。然后,我立即检查“left”属性,我理解它应该强制布局(因为浏览器必须重新计算元素的位置才能提供更新的值):
const colors = document.body.querySelectorAll("div")
const button = document.querySelector(".my-button")
button.onclick = handleClick
function handleClick ()
colors.forEach(color =>
color.style["left"] = "50px"
const left = color.style["left"] <--- This should force a Layout since "left" was just updated
)
html:
<html>
<head>
</head>
<body>
<button class="my-button">
Click
</button>
<div class="red-color">
red
</div>
<div class="blue-color">
blue
</div>
<div class="green-color">
green
</div>
<div class="yellow-color">
yellow
</div>
<div class="black-color">
black
</div>
</body>
</html>
CSS:
div
position: relative
在开发工具中,我希望看到在 for 循环的每次迭代中都会触发一个布局。具体来说,我正在寻找黄色的函数调用栏(应该对应于 handleClick 回调)下方的紫色布局栏(每次迭代一个)。相反,它看起来像在调用 handleClick 之后发生了一个 Layout:
以下是我的问题:
当我在处理 div 元素的位置并立即检查它们的新位置时,为什么在 handleClick 期间看不到任何布局被触发? 我是否应该期望看到在 for 循环的每次迭代中都会触发一个新布局?我会假设是这样,因为浏览器需要在每次迭代时提供更新的“左”位置。【问题讨论】:
奇怪,也许这是 v8 的某种优化。我设法通过在每次迭代之间等待一些毫秒来触发回流:jsfiddle.net/apz3gLjh 【参考方案1】:检查Element.style.property
值不会触发回流号。该值不是“计算值”,不需要重新计算布局。
const target = document.querySelector(".target");
target.style.left = "0px";
// logs "0px"
// even though the real computed value is "25px"
// from the !important rule in CSS
console.log( target.style.left );
target.classList.remove("begin");
target.style.left = "250px";
// now the computed style is correctly 250px
// but since we didn't trigger a reflow
// the transition doesn't kick in
.target
transition: left 2s;
width: 50px;
height: 50px;
background: salmon;
position: absolute;
.begin
/* will take precedence over the .style rule */
left: 25px !important;
<div class="target begin"></div>
也许你把它和getComputedStyle(element).property
混淆了,这会导致回流:
const target = document.querySelector(".target");
target.style.left = "0px";
// this triggers a reflow, the transition will kick in
console.log( getComputedStyle(target).left );
target.style.left = "250px";
.target
transition: left 2s;
width: 50px;
height: 50px;
background: salmon;
position: absolute;
<div class="target"></div>
【讨论】:
以上是关于为啥我在更改和检索元素位置时看不到布局/重排被触发?的主要内容,如果未能解决你的问题,请参考以下文章