使用 requestAnimationFrame 等待回流

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

我有一个元素,我想从

width: auto
过渡到固定宽度。 CSS 过渡不适用于
width: auto
,所以我需要 JavaScript 在过渡开始之前给元素一个固定的宽度:

element.style.width = element.scrollWidth + 'px';

然后我可以设置元素的目标宽度:

element.style.width = '420px';

不幸的是,大多数浏览器会将两行批处理到同一个回流中,从而阻止转换工作。我试过使用

requestAnimationFrame
等待回流,但它似乎立即执行。堆叠两个
requestAnimationFrame
调用按预期工作。为什么需要两次调用?为什么
requestAnimationFrame
立即运行回调很有用?

javascript css css-transitions
1个回答
0
投票

我想你在问为什么你需要回忆

requestAnimationFrame()
.

首先,

requestAnimationFrame()
不会立即运行,它会在下一个合理的时候运行。例如,如果您在另一个选项卡上,它不会运行,直到您回来。

另外,MDN 有这个注释:

注意:如果您想在下一次重绘时为另一个帧设置动画,则您的回调例程本身必须再次调用 requestAnimationFrame()。 requestAnimationFrame() 是 1 次拍摄。

不像

setInterval()
requestAnimationFrame()
只安排代码在下次运行动画代码是合理的时候运行,所以你必须召回它来安排另一个动画帧。

这可能更方便,因为根据发生的情况,您可能想在下一帧运行不同的函数,而

setInterval()
只允许您一遍又一遍地调用相同的函数。它还可以更好地结束动画:您需要做的就是不再调用它,而结束间隔需要显式调用
clearInterval()
.

const element = document.getElementById('box');

element.style.width = element.scrollWidth + 'px';

let width = element.scrollWidth;
function animateBox() {
  width -= 5;
  element.style.width = width + 'px';
  if (width >= 100) requestAnimationFrame(animateBox);
}
requestAnimationFrame(animateBox);
#box {
  height: 100px;
  background-color: red;
}
<div id="box"></div>

© www.soinside.com 2019 - 2024. All rights reserved.