Basically I'm trying to show an animation on certain elements that were affected in a "most recent action". After this animation completes it shouldn't play again. The problem I have at the moment is that I also define an animation which runs when the element(s) are "selected". When the element is deselected the original animation plays again, even if the animation-iteration-count
of 1 has been reached. I could certainly set up an event listener for when animationend
fires and then remove the class associated with the animation. I'm more trying to reason about why this doesn't work as intended. I guess this is sort of the opposite of this question.
document.querySelector('.one-time-animation').addEventListener("click", function(e) {
e.target.classList.toggle('selected');
})
.one-time-animation {
animation: one-time-animation 2s forwards 1;
}
.selected {
animation: selected 2s forwards 1;
}
@keyframes one-time-animation {
from {
background:red;
}
to {
background:transparent;
}
}
@keyframes selected {
from {
box-shadow: 0 0 0 green inset;
}
to {
box-shadow: 0 0 10px green inset;
}
}
<div class="one-time-animation">Click to toggle selected class</div>
Pure CSS Solution: (without polluting the
selected
style)Assuming the animation provided in question is the exact same used in your application and not just some random sample, you could actually replace it with a
transition
instead of ananimation
. This would also make sure that the original animation is never removed and hence never replayed.Reason:
The animations are working as they are supposed to be based on the specifications. On click, when the
selected
class is added to the element, it no longer hasone-time-animation
. This is because the latest specified value for theanimation
property over-rides the previous specified one (as rightly pointed out by shennan).When the
selected
class is toggled off, theone-time-animation
becomes applicable and by now the user-agent has no remembrance of this animation having been present on the element earlier. This results in the animation getting re-executed even though theanimation-iteration-count
is set to 1.One way to fix this issue would be to let the user agent know that the original animation is never really removed from the element. This can be performed by retaining it as part of the stack in the
selected
class. Animation property can support multiple animations in a comma separated format. The original animation doesn't run again because the user agent now treats it as ever present and thus maintains the iteration counter.If it is not possible to add the original animation as part of the stack for
selected
class (say because it is used for multiple elements each of which have different original animations) then the approach should be to get the currentanimation
, append theselected
animation to it and then set it via JS.I am not a JS expert but the below snippet should give you an idea of what I mean.
I believe the
animation-iteration-count
is reset when it is re-applied due to your toggling theselect
class. This is due to the cascading nature of CSS.One option would be to simply remove the
one-time-animation
class when you go to select it: