IE выполняет requestAnimationFrame после отрисовки, а не до

289
01 июля 2017, 13:12
Кратко:

В IE11 и Edge div в сниппете после клика становится зелёным, хотя не должен.

Подробно:

Рассмотрим следующую ситуацию: есть div чёрного цвета.
При клике по нему мы запрашиваем requestAnimationFrame и меняем цвет на зелёный.
В коллбеке requestAnimationFrame меняем цвет на красный.

Для наглядности в requestAnimationFrame добавлен цикл, вешающий браузер на 3 секунды, а на div повешена css-анимация, чтобы было ясно, что браузер повис.

Ожидаемое поведение (которое наблюдается в Chrome и Firefox):

  1. Есть черный div
  2. Происходит click
  3. Цвет формально меняется на зелёный, но перерисовки нет
  4. Без перерисовки вызывается коллбек requestAnimationFrame
  5. Браузер зависает на 3 секунды с чёрным div'ом на экране
  6. Цвет div'а меняется на красный
  7. Происходи перерисовка c красным div'ом

Однако, IE и Edge на шаге 5 показывают зелёный div. Насколько я понимаю, такое поведение некорректно, поскольку браузер обязан дождаться выполнения кода из requestAnimationFrame и только потом выполнить отрисовку на экране.

Как сделать, чтобы промежуточное состояние не отрисовывалось?

Вариант не изменять состояние без requestAnimationFrame не подходит, поскольку в реальной задаче (см. вопрос о canvas'е) эти изменения вызваны css-анимацией, а не скриптом. Кроме того, проблема проявляется даже при двух вложенных 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: Этот вопрос на английском.

READ ALSO
Как правильно вывести слэш через js?

Как правильно вывести слэш через js?

День добрый! Имеется код:

560
onclick для div в методе класса js

onclick для div в методе класса js

Здравствуйте, прошу помощи, объяснений, примеров) Пишу слайдер своими силами для сайта (намеренно не использую библиотеки) на чистом js по возможности...

240
Блоки одинаковой высоты

Блоки одинаковой высоты

Если заполняется один из блоков, то оба блока принимают наибольшую высотуВариант с фиксированной высотой не подойдет

266
Как добавить атрибут defer всем скриптам при загрузке страницы

Как добавить атрибут defer всем скриптам при загрузке страницы

Нужно добавить атрибут defer при загрузке страницы всем <script>-амТаким образом хочу ускорить загрузку страницы

289