我正在尝试同步接收相同动画类的多个页面元素的 CSS 动画。
似乎有很多关于这个主题的帖子,但没有统一的解决方案,而且我找到的解决方案似乎都不适用于这种情况。
我在这里准备了一个jsfiddle来演示这个问题:
https://jsfiddle.net/gdf7szo5/1/ https://jsfiddle.net/gdf7szo5/1/
如果您单击任何字母,它将启动该字母的动画。如果您再次单击,它将切换到不同的动画,如果您第三次单击,它将把字母设置为根本没有动画。
期望的效果是一个动画中闪烁的所有字母彼此同步,并且另一动画中的任何字母彼此同步。需要明确的是,我并不是试图同步两个动画 - 我只是希望具有给定动画的所有元素彼此同步。
但目前,如果一个字母显示动画,而您将另一个字母设置为同一动画,除非您有绝对完美的时机,否则这两个字母的动画将不同步,即使它们是相同的动画。
这是正在运行的代码:
HTML:
<div>
<span id="spA" onclick="toggleFx('spA')">A</span>
<span id="spB" onclick="toggleFx('spB')">B</span>
<span id="spC" onclick="toggleFx('spC')">C</span>
<span id="spD" onclick="toggleFx('spD')">D</span>
</div>
CSS:
div {
display: flex;
flex-flow: column;
}
span {
animation-name: pulse_active;
}
span.pulse {
color: #f00;
animation: pulse_active 1.5s ease-in infinite;
}
span.pulse_invert {
color: #00f;
animation: pulse_inverted 3s ease-in infinite;
}
@keyframes pulse_active {
0% {
opacity: 0;
}
50% {
opacity: 0.66;
}
100% {
opacity: 0;
}
}
@keyframes pulse_inverted {
0% {
opacity: 1;
}
50% {
opacity: 0.33;
}
100% {
opacity: 1;
}
}
JS:
let pulseNormal = {};
let pulseInvert = {};
function toggleFx(spanID) {
let spanTarget = document.getElementById(spanID);
// shift setting
if (spanID in pulseInvert) {
console.log('y');
console.log(Object.keys(pulseInvert));
delete pulseInvert[spanID]
console.log(Object.keys(pulseInvert));
} else if (spanID in pulseNormal) {
pulseInvert[spanID] = true;
delete pulseNormal[spanID];
} else {
pulseNormal[spanID] = true
}
// update display
for (let sp of 'ABCD') {
let span = document.getElementById(`sp${sp}`);
// clear any prev animation
span.classList.remove('pulse');
span.classList.remove('pulse_invert');
// add/re-add animation as needed
if (`sp${sp}` in pulseNormal) {
span.classList.add('pulse');
} else if (`sp${sp}` in pulseInvert) {
span.classList.add('pulse_invert');
}
}
}