【发布时间】:2021-11-03 05:35:15
【问题描述】:
我已经创建了简单的演示,让我们开始吧...
应该说一下我们有什么用chrome和firefox对比一下
演示 1:
block.addEventListener("click", () => {
block.style.transform = "translateX(500px)";
block.style.transition = "";
block.style.transition = "transform 1s ease-in-out";
block.style.transform = "translateX(100px)";
});
.main {
width: 100px;
height: 100px;
background: orange;
}
<div id="block" class="main"></div>
在两种浏览器中,我们都看不到任何变化
演示 2:
block.addEventListener("click", () => {
block.style.transform = "translateX(500px)";
block.style.transition = "";
requestAnimationFrame(() => {
block.style.transition = "transform 1s ease-in-out";
block.style.transform = "translateX(100px)";
});
});
.main {
width: 100px;
height: 100px;
background: orange;
}
<div id="block" class="main"></div>
在 chrome 中我们会看到动画,在 Firefox 中我们会看到另一件事。需要提到的是,Firefox 符合 Jake Archibald in the Loop 视频中的操作。但不是在铬的情况下。似乎firefox符合规范,但不符合chrome
演示 2(替代):
block.addEventListener("mouseover", () => {
block.style.transform = "translateX(500px)";
block.style.transition = "";
requestAnimationFrame(() => {
block.style.transition = "transform 1s ease-in-out";
block.style.transform = "translateX(100px)";
});
});
.main {
width: 100px;
height: 100px;
background: orange;
}
<div id="block" class="main"></div>
现在我们看到 chrome 可以正常工作,但是 firefox 和 Demo 2 中的 chrome 做的一样。他们已经改变了他们的位置 我还测试了事件:mouseenter、mouseout、mouseover、mouseleave、mouseup、mousedown。最有趣的是最后两个在 chrome 和 firefox 中的工作方式相同,我认为它们都是不正确的。
总结:这两个 UA 对事件的处理方式似乎不同。但是他们是怎么做的呢?
演示 3:
block.addEventListener("click", () => {
block.style.transform = "translateX(500px)";
block.style.transition = "";
requestAnimationFrame(() => {
requestAnimationFrame(() => {
block.style.transition = "transform 1s ease-in-out";
block.style.transform = "translateX(100px)";
});
});
});
.main {
width: 100px;
height: 100px;
background: orange;
}
<div id="block" class="main"></div>
通过 Archibald 的话,在这里我们看到 firefox 和 chrome 一样好用,这是预期的。但是你还记得演示 2,两个版本,为什么它们的行为如此不同?
【问题讨论】:
-
我离开键盘几天了,所以我还不能给出答案,但请注意,当回流发生时,你的两个第一个 sn-ps 中没有任何东西,只有第三个一个是肯定的。如果您想要始终转换到工作状态,请强制进行回流,如下所示:stackoverflow.com/questions/55134528/… 如果您对两种实现中发生的情况感兴趣,请等几天,我会写这篇文章。
-
@Kaiido 我对你完整的答案很好奇,我会等的。你对我的回答太好了,我很高兴:)
-
@Kaiido 在你完成你的答案之前,我想问一件事(我想自己阅读)。当我在 chrome 浏览器的开发工具中检查性能选项卡时,我注意到我看到了下一个动作链:动画帧触发 => 重新计算样式 => 更新层树 => 绘制 => 复合层。而且我已经阅读了一些关于事件循环的规范,但我没有看到有关重新计算样式和使用合成更新图层树的步骤。都在哪里?
-
这不是规范的一部分,实施者可以随心所欲。在我链接到的答案中,实际上已经解释了这部分的链接,请参阅stackoverflow.com/questions/47342730/…
-
@Kaiido 那么应该如何理解这些步骤放在哪里呢?嗯,我已经阅读了您的链接,但我仍然正确理解步骤
11. Update the rendering: if this is a window event loop, then:和子步骤16. For each fully active Document in docs, update the rendering or user interface of that Document and its browsing context to reflect the current state中的内容,这里 16 步的意思是:recalculate styles => update layer tree => paint => composite layers...我正确吗? html.spec.whatwg.org/multipage/…
标签: javascript google-chrome firefox event-loop