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; 
&lt;div&gt;&lt;/div&gt;

PS:Same question in Russian.

【问题讨论】:

不确定是否相关,但你有:var t = new Date;while (new Date &lt; t);,应该是:var t = new Date();while (new Date() &lt; 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; 
&lt;div&gt;&lt;/div&gt;

我使用该解决方案来计算具有 display: none; 的元素的宽度或高度。然后在 requestAnimationFrame 中重新隐藏元素,只有在 IE 上才能看到元素可见的时刻。

【讨论】:

以上是关于IE 在 requestAnimationFrame 之前执行渲染的主要内容,如果未能解决你的问题,请参考以下文章

requestAnimationFrame (待整理)

在 Angular 中对 requestAnimationFrame 进行单元测试的选项都有哪些?

为啥在循环开始时调用 requestAnimationFrame 不会导致无限递归?

requestAnimationFrame 方法你真的用对了吗?

在 requestAnimationFrame 游戏循环中跟踪时间/帧的最佳方法是啥?

详解Web API requestAnimationFrame