Reputation: 5179
I have tried out the transitionend
and animationend
to change my css after a transition
or keyframes
animation ends. I made an example with both variants and they worked as expected: I can toggle
a class
, when a transition
or animation ends. On hover, I start the transition/animation and in JavaScript
I toggle a class, which changes the background-color
, after the transition/animation changes.
The only difference is, that when I do the mouseout and the div goes back to the original state, with transition
and transitionend, the class will be removed and the original background-color
is visible. For keyframes
animations and animationend
, the class and background-color
stay, also when I do the mouseout. How can I get the same behavoir for the animationend
like the transition
?
var boxTransition = document.getElementById("transition");
var boxAnimation = document.getElementById("animation");
/* add class after transition ends */
boxTransition.addEventListener("transitionend", changeBackground);
/* add class after keyframes animation ends */
boxAnimation.addEventListener("animationend", changeBackground);
function changeBackground() {
this.classList.toggle("box--end");
}
.box {
height: 100px;
margin-bottom: 30px;
width: 100px;
}
.box--transition {
background-color: lightcoral;
transition: width 0.5s ease-in-out;
}
.box--transition:hover {
width: 300px;
}
.box--animation {
background-color: lightblue;
}
.box--animation:hover {
animation: animateWidth 0.5s ease-in-out;
animation-fill-mode: forwards;
}
.box--end {
background-color: gray;
}
@keyframes animateWidth {
from {
width: 100px;
}
to {
width: 300px;
}
}
<div id="transition" class="box box--transition"></div>
<div id="animation" class="box box--animation"></div>
Upvotes: 1
Views: 1193
Reputation: 1676
I can see 2 options for you.
First one is to call changeBackground
on boxAnimation.onMouseOut()
:
boxAnimation.addEventListener("mouseout", changeBackground);
That will change background immediately.
Second is to set animation for .box--animation
without hover:
@keyframes animateWidth2 {
from {
width: 300px;
}
to {
width: 100px;
}
}
.box--animation {
animation: animateWidth2 0.5s ease-in-out;
animation-fill-mode: forwards;
}
That will work like transition, but will happen on start too.
To prevent this happen from start you can add .box--hovered
class to .box
in changeBackground()
and add animation to .box--animation.box--hovered
instead of just .box--animation
.
Example for second variant.
Upvotes: 1
Reputation: 4014
You should note that animation and transition are not the same, Thus event handling here is a bit trikcy.
I am going to explain what happens on both of them.
Transition: It's just the animating part of an element's changing property.
Example, it could be width or height or color. It is assigned on :hover
usually.
Thus, it does not wait for animation if a user takes the mouse out of the element before the transition completes.
On the other hand,
Animation: is a complete set of transition and does not care about the user's mouseout
event, once starts, it ends on it's own.
So, here is what you can do. As you assigned the toggle on transitionend
it's okay because whenever the user takes the mouse out, transition completes and then the event triggers, but for animation, you should take care of them explicitly.
What I did is, (assuming user will keep the mouse on the element for a few second) added the class once animation has ended (like transitionend
) then removed the class once the user takes the mouse out of the element.
Not exactly this is what you should do, but you can now get an idea on what to do and when.
Demo:
var boxTransition = document.getElementById("transition");
var boxAnimation = document.getElementById("animation");
/* add class after transition ends */
boxTransition.addEventListener("transitionend", changeBackground);
/* add class after keyframes animation ends */
boxAnimation.addEventListener("animationend", greyOnStart);
boxAnimation.addEventListener("mouseout", revertOnEnd);
function changeBackground() {
this.classList.toggle("box--end");
}
function greyOnStart(){
this.classList.add('box--end');
}
function revertOnEnd(){
this.classList.remove('box--end');
}
.box {
height: 100px;
margin-bottom: 30px;
width: 100px;
}
.box--transition {
background-color: lightcoral;
transition: width 0.5s ease-in-out;
}
.box--transition:hover {
width: 300px;
}
.box--animation {
background-color: lightblue;
}
.box--animation:hover {
animation: animateWidth 0.5s ease-in-out;
animation-fill-mode: forwards;
}
.box--end {
background-color: gray;
}
@keyframes animateWidth {
from {
width: 100px;
}
to {
width: 300px;
}
}
<div id="transition" class="box box--transition"></div>
<div id="animation" class="box box--animation"></div>
Upvotes: 4