为什么 CSS 转换在页面加载时不起作用?

Why don't CSS transitions work on page load?

在页面加载时执行 JavaScript 代码时,使用 JavaScript 更改 CSS 属性似乎不适用于转换。

这是一个例子:

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Test</title>
  <style>
    div {
      background: red;
      width: 300px;
      height: 300px;
      transition: 0.5s;
    }
  </style>
</head>
<body>
  <div />
  <script>
    var div = document.querySelector("div");

    // the following doesn't work as intended
    div.style.marginTop = "100px";

    // the following works fine
    /*setTimeout(() => (
    div.style.marginTop = "100px"
    ), 0);*/
  </script>
</body>
</html>

这可以通过封装要在对 setTimeout() 的调用中进行的更改来解决,即使将 0 作为第二个参数。

谁能给我解释一下这种行为?

JavaScript代码在第一帧之前运行。并且因为渲染的第一帧已经具有更改的值,所以没有开始过渡。

setTimeout(...,0) 有效,因为 setTimeout 创建一个回调并等待主线程空闲,这是在渲染过程之后。

将您的 JS 包装在 window.onload 函数中,该函数在 整个页面加载后 被触发,包括其内容(图像、css、脚本、等...) 将解决此问题。

window.onload = function () {
    var div = document.querySelector("div");

    // the following doesn't use the transition
    div.style.marginTop = "100px";

    // the following uses the transition
    /*setTimeout(() => (
      div.style.marginTop = "100px"
    ), 0);*/
};
div {
  background: red;
  width: 300px;
  height: 300px;
  transition: 1s;
}
<div />