我在理解requestAnimationFrame API时遇到了一些困难。我认为这会让浏览器等待回调完成,直到浏览器触发重新绘制(还是重新流?)。对吗?如果在回调中调用requestAnimationFrame,浏览器将重新绘制并执行新的RAF回调,然后再重新绘制吗?如果是这样的话,我如何才能对这个API进行两个顺序调用,而不是像下面的示例那样嵌套它们呢?
在这里,我使用了翻转技术将文档片段插入到DOM中,并将DOM元素的高度动画化,它似乎工作得很好。我不喜欢代码的回调特性/嵌套。我很难理解如何才能使这个更异步。是否有可能利用一个承诺,并使它变得容易接受?
window.requestAnimationFrame(() => {
this.appendChild(frag);
this.style.height = `${rows * rowHeight}px`;
const { top: after } = this.getBoundingClientRect();
this.style.setProps({
"transform" : `translateY(${before - after}px)`,
"transition" : "transform 0s"
});
window.requestAnimationFrame(() => {
this.style.setProps({
"transform" : "",
"transition" : "transform .5s ease-out"
});
});
});
那么,我对皇家空军的先入为主的看法正确吗?而且,上面的代码示例怎么可能没有回调,而不是嵌套的呢?
发布于 2019-03-13 01:22:51
我不确定您是否会对requestAnimationFrame
有自己的解释,但简单地说,它只是一个setTimeout(fn, the_time_until_painting_frame)
。
简单地说,它将fn
放在一个回调列表中,当下一个绘图事件循环发生时,所有回调都将被执行。这个画图事件循环是一个特殊的事件循环,浏览器将调用自己的绘画操作(CSS动画、WebAnimations等),它们将每n次标记一个事件循环为这样的画框。这通常与屏幕刷新速率同步.
因此,我们的rAF回调将在此事件循环中执行,就在浏览器执行其绘制操作之前。
现在,您偶然发现浏览器是如何计算CSS转换的:它们采用元素的当前计算值。
但是这些计算值不是同步更新的。浏览器通常会等待这个画框来重新计算,因为要计算一个元素,您需要重新计算所有CSSOM树。
幸运的是,有些DOM方法将同步触发这样的再流,因为它们确实需要更新方框值,例如Element.offsetTop
getter。
因此,只需在设置初始样式(包括转换样式)之后调用这些方法之一,就可以同步触发转换:
_this.style.height = "50px";
_this.style.setProperty("transform", "translateY(140px)");
_this.style.setProperty("transition", "transform 0s");
_this.offsetTop; // trigger reflow
_this.style.setProperty("transform", "");
_this.style.setProperty("transition", "transform .5s ease-out");
#_this {
background: red;
width: 50px;
}
<div id="_this"></div>
https://stackoverflow.com/questions/55137979
复制相似问题