我有一个元素,我想从
width: auto
过渡到固定宽度。 CSS 过渡不适用于 width: auto
,所以我需要 JavaScript 在过渡开始之前给元素一个固定的宽度:
element.style.width = element.scrollWidth + 'px';
然后我可以设置元素的目标宽度:
element.style.width = '420px';
不幸的是,大多数浏览器会将两行批处理到同一个回流中,从而阻止转换工作。我试过使用
requestAnimationFrame
等待回流,但它似乎立即执行。堆叠两个 requestAnimationFrame
调用按预期工作。为什么需要两次调用?为什么 requestAnimationFrame
立即运行回调很有用?
我想你在问为什么你需要回忆
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>