我有几个相同类型的元素,我希望它们共享相同的CSS动画,但是我希望它们在不同的时间开始/结束动画。
Codepen for the following code
html:
<div class="container">
<div class="box hidden"></div>
</div>
<div class="container">
<div class="box hidden"></div>
</div>
<div class="container">
<div class="box hidden"></div>
</div>
css:
.container {
width: 100px;
height: 100px;
margin-bottom: 20px;
}
.box {
width: 100%;
height: 100%;
}
.box.hidden {
visibility: hidden;
}
.box {
animation: growIn 1s;
animation-timing-function: cubic-bezier(.46,.13,.99,.83);
transition: all .2s cubic-bezier(0.215, 0.61, 0.355, 1);
}
.container:first-child .box {
background-color: green;
}
.container:nth-child(2) .box {
background-color: orange;
}
.container:nth-child(3) .box {
background-color: red;
}
@keyframes growIn {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
box
元素开始时是隐藏的,然后使用javascript从不同的框中但在不同的时间删除了该类名:
const boxes = document.querySelectorAll(".box");
boxes.forEach(box => {
setTimeout(() => box.classList.remove("hidden"), Math.random() * 1000);
});
发生的是,所有3个盒子都在同一时间结束动画。动画的确开始于不同的时间,但全部都结束了。
那是为什么?
如果我做同样的事情,但是添加了一个类名而不是删除它(以使动画开始),那么它的行为就像我想要的那样。
有任何想法吗?谢谢。
答案 0 :(得分:2)
仅是因为所有动画均已已同时开始。使用visibility:hidden
不会阻止动画开始,并且使动画在元素可见时稍后开始。例如,不透明度也会发生同样的事情:
const boxes = document.querySelectorAll(".box");
boxes.forEach(box => {
setTimeout(() => box.classList.remove("hidden"), Math.random() * 5000);
});
.container {
width: 100px;
height: 100px;
margin-bottom: 20px;
}
.box {
width: 100%;
height: 100%;
}
.box.hidden {
opacity: 0.1;
}
.box {
animation: growIn 5s;
animation-timing-function: cubic-bezier(.46, .13, .99, .83);
transition: all .2s cubic-bezier(0.215, 0.61, 0.355, 1);
}
.container:first-child .box {
background-color: green;
}
.container:nth-child(2) .box {
background-color: orange;
}
.container:nth-child(3) .box {
background-color: red;
}
@keyframes growIn {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
<div class="container">
<div class="box hidden"></div>
</div>
<div class="container">
<div class="box hidden"></div>
</div>
<div class="container">
<div class="box hidden"></div>
</div>
如果您改用display
属性,则可以看到所需的行为:
const boxes = document.querySelectorAll(".box");
boxes.forEach(box => {
setTimeout(() => box.classList.remove("hidden"), Math.random() * 3000);
});
.container {
width: 100px;
height: 100px;
margin-bottom: 20px;
}
.box {
width: 100%;
height: 100%;
}
.box.hidden {
display:none;
}
.box {
animation: growIn 1s;
animation-timing-function: cubic-bezier(.46, .13, .99, .83);
transition: all .2s cubic-bezier(0.215, 0.61, 0.355, 1);
}
.container:first-child .box {
background-color: green;
}
.container:nth-child(2) .box {
background-color: orange;
}
.container:nth-child(3) .box {
background-color: red;
}
@keyframes growIn {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
<div class="container">
<div class="box hidden"></div>
</div>
<div class="container">
<div class="box hidden"></div>
</div>
<div class="container">
<div class="box hidden"></div>
</div>
“可见性”属性指定是否由 元素已呈现。
不可见的框仍会影响布局(设置 将“显示”属性设置为“无”,以完全禁止生成框)。
因此,与使用visibility
相比,使用display
时会始终生成框。
如果我们检查与动画有关的specification,我们会发现:
将display属性设置为none将终止任何运行 应用于元素及其后代的动画。如果一个元素 无显示,将显示更新为无值 将以动画名称开始应用于元素的所有动画 属性,以及应用于带有 不显示任何内容。
答案 1 :(得分:1)
问题是您的box元素以.box类(动画类)开头。这意味着动画从加载元素的那一刻开始,无论是否隐藏。这意味着,当您删除“隐藏”类时,它们只会在动画过程中的某个时刻展现自己。
您要做的是重命名动画类,例如“ grower”
.grower {
animation: growIn 1s;
animation-timing-function: cubic-bezier(.46,.13,.99,.83);
transition: all .2s cubic-bezier(0.215, 0.61, 0.355, 1);
}
然后在javascript循环中添加它:
const boxes = document.querySelectorAll(".box");
boxes.forEach(box => {
setTimeout(() => {
box.classList.remove("hidden");
box.classList.add("grower"); }, Math.random() * 1000);
});
下面是一个演示它的片段:
const boxes = document.querySelectorAll(".box");
boxes.forEach(box => {
setTimeout(() => {
box.classList.remove("hidden");
box.classList.add("grower"); }, Math.random() * 1000);
});
.container {
width: 100px;
height: 100px;
margin-bottom: 20px;
}
.box {
width: 100%;
height: 100%;
}
.box.hidden {
visibility: hidden;
}
.grower {
animation: growIn 1s;
animation-timing-function: cubic-bezier(.46,.13,.99,.83);
transition: all .2s cubic-bezier(0.215, 0.61, 0.355, 1);
}
.container:first-child .box {
background-color: green;
}
.container:nth-child(2) .box {
background-color: orange;
}
.container:nth-child(3) .box {
background-color: red;
}
@keyframes growIn {
from {
transform: scale(0);
}
to {
transform: scale(1);
}
}
<div class="container">
<div class="box hidden"></div>
</div>
<div class="container">
<div class="box hidden"></div>
</div>
<div class="container">
<div class="box hidden"></div>
</div>