0

我想做以下事情:创建一个 div (#test),然后多次克隆该 div,每次克隆它时都会通过 javascript 添加一个 css 转换。第一次一切正常,但如果我尝试第二次克隆并应用 css 过渡,则过渡不起作用。

在此示例中(https://jsfiddle.net/9uL1qt6n/13/),红色方块按预期移动,但绿色方块没有移动,并立即出现在过渡结束时。

这是我正在使用的 javascript 代码:

function move(color){
  let clone=document.getElementById("test").cloneNode(true);
  clone.id=color;
  clone.style.display="block";
  clone.style.backgroundColor=color;
  document.getElementById("main").prepend(clone);
  setTimeout(function(){
      clone.style.left="500px";
  },0)
}

setTimeout(function(){move("red")},500);
setTimeout(function(){move("green")},750);

我期望红色方块在 0.5 秒时以 left=0px 开始并向右移动,然后是在 0.75 秒时以 left=0px 开始并向右移动的绿色方块。我看到的是一个红色方块,在 0.5 秒处以 left=0px 开始并向右移动,然后是一个在 0.75 秒处以 left=500px 开始并且不移动的绿色方块。

编辑:这似乎在 Mac 上的 Safari 以及 iOS 中的 Safari 和 Chrome 上正常工作。以上建议的行为仅出现在 Mac 上的 Chrome 上。

4

1 回答 1

1

这是因为setTimeout(/**/, 0)不保证回调将在后续帧上执行。这可能(取决于浏览器实现和计算机速度)导致样式应用在与插入 DOM 的节点相同的帧上。

理论上,您应该改用requestAnimationFrame它,这正是针对这种情况的意思。

但是,在您链接的小提琴中,只有当我将requestAnimationFrame不可察觉但仍然不可取的翻倍时,它才有效... IDK 如果它是 JSFiddle 的侥幸或什么...

function move(color){
  let clone=document.getElementById("test").cloneNode(true);
  clone.id=color;
  clone.style.display="block";
  clone.style.backgroundColor=color;
  document.getElementById("main").prepend(clone);
  requestAnimationFrame(() => {
    requestAnimationFrame(() => {
        clone.style.left="500px";
    })
  })
}

这是一个片段:我在 SO 片段中找到了同样的东西

function move(color) {
  let clone = document.getElementById("test").cloneNode(true);
  clone.id = color;
  clone.style.display = "block";
  clone.style.backgroundColor = color;
  document.getElementById("main").prepend(clone);
  requestAnimationFrame(() => {
    requestAnimationFrame(() => {
      clone.style.left = "500px";
    })
  })
}


setTimeout(() => move("red"), 500);
setTimeout(() => move("green"), 750);
#main {
  display: block;
  width: 100vw;
  height: 100vh;
  background-color: blue;
}

.test {
  position: absolute;
  display: none;
  width: 100px;
  height: 100px;
  background-color: red;
  transition: left 1s ease;
  transform: scale(1);
  left: 0px;
}
<div id="main"></div>
<div id="test" class="test"></div>

于 2020-10-25T21:49:28.750 回答