IE 在 requestAnimationFrame 之前执行渲染
Posted
技术标签:
【中文标题】IE 在 requestAnimationFrame 之前执行渲染【英文标题】:IE performs rendering before requestAnimationFrame 【发布时间】:2017-06-29 22:20:33 【问题描述】:下面 sn-p 中的 Div 在单击后不应变为绿色,但在 IE 11 和 Edge 中会。
我们来看看下面的情况:有一个黑色的div
。
单击它时,我们调用requestAnimationFrame
并立即将颜色更改为绿色。
在requestAnimationFrame
collback 中,我们将颜色更改为红色。
为了获得更多可见性,我在requestAnimationFrame
中添加了一个循环,它会产生 3 秒的延迟。我还添加了一个 CSS 动画来显示延迟在哪里。
我期望以下行为(并在 Chrome 和 Firefox 中看到):
-
有一个黑色
div
click
发生
颜色正式更改为绿色,但未渲染
不调用requestAnimationFrame
的渲染回调
浏览器延迟 3 秒,屏幕显示黑色 div
div
的颜色变为红色
进行渲染并显示红色 div
但是,第 5 步中的 IE11 和 Edge 显示 绿色 div。我认为这种行为是不正确的,因为浏览器必须推迟重新渲染,直到 requestAnimationFrame
处理程序被执行。
如何强制 IE/Edge 在渲染之前调用处理程序?
我无法阻止 requestAnimationFrame
之前的更改,因为在我的实际代码中它们是由 CSS 动画引起的。即使在 2 次递归调用 requestAnimationFrame
的情况下也会出现此问题。
https://jsfiddle.net/8Ljn14ee/2/
var div = document.querySelector('div');
div.addEventListener('click', function ()
requestAnimationFrame(function ()
var t = new Date;
t.setSeconds(t.getSeconds() + 3);
while (new Date < t);
div.style.background = 'red';
);
div.style.background = 'green';
);
div
height: 200px;
width: 200px;
border-radius: 50%;
background: black;
animation: w-100-200 3s linear infinite;
@keyframes w-100-200
0% width: 200px;
50% width: 400px;
100% width: 200px;
<div></div>
PS:Same question in Russian.
【问题讨论】:
不确定是否相关,但你有:var t = new Date;
和 while (new Date < t);
,应该是:var t = new Date();
和 while (new Date() < t);
@ScottMarcus,不,不应该。那是一样的。顺便说一句,你可以看到,它确实有效。
您能否为此提供一些文档。我没有看到here 列出的语法。如果您不添加括号,您可能会得到正确的日期/时间,但是当您尝试在返回的对象上调用方法时(如.setSeconds()
),这将是一个问题,因为这是一个实例方法并且没有括号,你得到一个值,但不是一个实例,因为你没有调用 Date
作为构造函数。
@ScottMarcus, developer.mozilla.org/en-US/docs/Web/javascript/Reference/… 说new constructor[([arguments])]
- 如您所见,如果没有参数,大括号可以省略。
@ScottMarcus,只需检查您是否不信任:jsfiddle.net/8Ljn14ee/4 这部分的工作方式与括号相同。不,如果我在没有new
的情况下调用它,我会得到值(字符串)。对于new
,它是一个Date
对象。
【参考方案1】:
好像Edge上正在考虑这个问题
我认为这是因为 IE 执行 requestAnimationFrame 的速度不够快或者延迟了一点,所以它执行了 div.style.background = 'green';而其他浏览器则没有。
我在 IE 上的 requestAnimationFrame 也有类似的问题,我认为这是同样的问题,请检查小提琴,即单击圆圈,当其他浏览器不这样做时,你会看到它变绿。
https://jsfiddle.net/8Ljn14ee/13/
var div = document.querySelector('div');
div.addEventListener('click', function ()
div.style.background = 'green';
requestAnimationFrame(function ()
div.style.background = 'red';
);
);
div
height: 200px;
width: 200px;
border-radius: 50%;
background: black;
animation: w-100-200 3s linear infinite;
@keyframes w-100-200
0% width: 200px;
50% width: 400px;
100% width: 200px;
<div></div>
我使用该解决方案来计算具有 display: none; 的元素的宽度或高度。然后在 requestAnimationFrame 中重新隐藏元素,只有在 IE 上才能看到元素可见的时刻。
【讨论】:
以上是关于IE 在 requestAnimationFrame 之前执行渲染的主要内容,如果未能解决你的问题,请参考以下文章
在 Angular 中对 requestAnimationFrame 进行单元测试的选项都有哪些?
为啥在循环开始时调用 requestAnimationFrame 不会导致无限递归?
requestAnimationFrame 方法你真的用对了吗?