Я не уверен, что получу ваше собственное объяснение requestAnimationFrame
, но, проще говоря, это просто setTimeout(fn, the_time_until_painting_frame)
.
Проще говоря, он помещает fn
в список обратных вызовов, которые все будут выполнены, когда произойдет следующий цикл событий рисования. Этот цикл событий рисования представляет собой специальный цикл событий, в котором браузеры будут вызывать свои собственные операции рисования (CSS-анимации, WebAnimations и т. Д.) Они будут отмечать один цикл событий каждый n-й раз, чтобы быть таким фреймом рисования. обычно синхронизируется с частотой обновления экрана.
Таким образом, наши обратные вызовы rAF будут выполняться в этом цикле событий непосредственно перед тем, как браузер выполнит свои операции рисования.
Теперь вы наткнулись на то, как браузер вычисляет переходы CSS: они принимают текущие вычисленные значения вашего элемента.
Но эти вычисленные значения не обновляются синхронно. Браузеры обычно ждут эту рамку рисования , чтобы выполнить recalc , потому что для вычисления одного элемента вам необходимо пересчитать все дерево CSSOM.
К счастью для вас, есть некоторые методы DOM, которые синхронно инициируют такое перекомпонование, потому что им нужны обновленные значения box, например, 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>