Chrome 在 OSX 上:CSS 转换立即应用于 div 的第二个克隆
Chrome on OSX: CSS transitions applied immediately to second clone of div
我想执行以下操作:创建一个 div (#test),然后多次克隆 div,每次克隆时都添加一个 css 过渡通过 javascript。第一次一切正常,但如果我第二次尝试克隆并应用 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);
我希望红色方块以 left=0px 开始并在 .5s 处向右移动,然后绿色方块以 left=0px 开始并在 .75s 处向右移动。我看到的是一个以 left=0px 在 .5s 开始并向右移动的红色方块,然后是一个在 .75s 以 left=500px 开始并且不移动的绿色方块。
编辑: 这似乎在 Mac 上的 Safari 以及 iOS 中的 Safari 和 Chrome 上正常工作。以上建议的行为仅出现在 Mac 上的 Chrome 上。
这是因为setTimeout(/**/, 0)
不保证回调会在后续帧上执行。这可能(取决于浏览器实现和计算机速度)导致将样式应用到与插入到 DOM.
中的节点相同的框架上
理论上,您应该使用requestAnimationFrame
来代替,这正是针对这种情况的。
但是,在您链接的 fiddle 中,只有当我将 requestAnimationFrame
加倍时它才有效,这是难以察觉但仍然不受欢迎的......如果它是 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>
我想执行以下操作:创建一个 div (#test),然后多次克隆 div,每次克隆时都添加一个 css 过渡通过 javascript。第一次一切正常,但如果我第二次尝试克隆并应用 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);
我希望红色方块以 left=0px 开始并在 .5s 处向右移动,然后绿色方块以 left=0px 开始并在 .75s 处向右移动。我看到的是一个以 left=0px 在 .5s 开始并向右移动的红色方块,然后是一个在 .75s 以 left=500px 开始并且不移动的绿色方块。
编辑: 这似乎在 Mac 上的 Safari 以及 iOS 中的 Safari 和 Chrome 上正常工作。以上建议的行为仅出现在 Mac 上的 Chrome 上。
这是因为setTimeout(/**/, 0)
不保证回调会在后续帧上执行。这可能(取决于浏览器实现和计算机速度)导致将样式应用到与插入到 DOM.
理论上,您应该使用requestAnimationFrame
来代替,这正是针对这种情况的。
但是,在您链接的 fiddle 中,只有当我将 requestAnimationFrame
加倍时它才有效,这是难以察觉但仍然不受欢迎的......如果它是 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>