Reputation: 65
This is my CSS, in which, three keyframes are bound together to make a chain animation
#anim-div{
-webkit-animation-name : mpbar-anim-page1, mpbar-anim-page2, mpbar-anim-page3;
animation-name : mpbar-anim-page1, mpbar-anim-page2, mpbar-anim-page3;
-webkit-animation-delay : 0s, 0.7s, 1.4s;
animation-delay : 0s, 0.7s, 1.4s;
-webkit-animation-duration: 0.7s;
animation-duration : 0.7s;
}
Is it possible to detect animationend event of the whole set?
when I try, it detects animationend for each individual keyframes (ending up firing 3 events)
Upvotes: 2
Views: 1115
Reputation: 6796
Assuming that the number of animations is unknown and the name of the final animation is also unknown, you could achieve this by using getComputedStyle
to read the animations into an array. Then, when the animationend
event fires, increment a variable and execute the code you wish when the value of that variable equals the length of the array, like so:
var div=document.querySelector("div"),
style=window.getComputedStyle(div),
animation=style.getPropertyValue("animation-name")||style.getPropertyValue("-moz-animation-name")||style.getPropertyValue("-webkit-animation-name"),
// Delete unneeded prefixed properties above
count=animation?animation.split(",").length:0,
ended=0;
div.addEventListener("animationend",function(){
ended++;
if(ended===count){
// Your code here
console.log(ended+" animations completed.");
}
},0);
div{
animation:x 1s ease-in-out,y 1s ease-in-out 1s,z 1s ease-in-out 2s;
background:#000;
height:50px;
width:50px;
}
@keyframes x{to{transform:rotatex(180deg);}}
@keyframes y{to{transform:rotatey(180deg);}}
@keyframes z{to{transform:rotatez(180deg);}}
/* Housekeeping */
body,html{height:100%;}
body{align-items:center;display:flex;justify-content:center;}
<div></div>
Upvotes: 3
Reputation: 8461
We can assume that the animationend event of the whole set is actually the animationend event of the animation that ends last (in our case, the third animation).
So in the animationend event that is binded to our element, we need to detect the name of the animation that has just ended and check if it matches the third animation.
We can acces the originalEvent
object and get the animationName
property.
Try the following code:
$(document).ready(function(){
$('#anim-div').on(animationEvent, function(e){
var animationName = e.originalEvent.animationName;
if (animationName == 'mpbar-anim-page3') {
console.log('"' + animationName + '" animation has finished');
}
});
});
I've used the variable animationEvent
to get the correct name of the animationend event (some browsers may require a prefixed version). You need to put the folllowing code before the one above:
function whichAnimationEvent(){
var t,
el = document.createElement("fakeelement");
var animations = {
"animation" : "animationend",
"OAnimation" : "oAnimationEnd",
"MozAnimation" : "animationend",
"WebkitAnimation": "webkitAnimationEnd"
}
for (t in animations){
if (el.style[t] !== undefined){
return animations[t];
}
}
}
var animationEvent = whichAnimationEvent();
I've also put the complete code in a fiddle: https://jsfiddle.net/psxxbp2y/.
Tested in Firefox, Chrome and Opera.
Upvotes: 3