I'm having some trouble in my JavaScript deciding whether to wait for animationend
events or not and wondered if an elegant solution to this problem exists.
Lets say that I have a div that animates on page load and fades in, then at a later time I have another script that appends an <img>
tag to the div.
I want the <img>
to be appended after the animation has completed in order to avoid any stuttering during the animation and to just make it look nicer.
Currently I know that I can write something like this (assuming I use animate.css):
HTML:
<div class="append-image-here animated fadeIn"></div>
JavaScript:
$(function() {
$('.append-image-here').one([
'webkitAnimationEnd',
'mozAnimationEnd',
'MSAnimationEnd',
'oanimationend',
'animationend'
].join(' '), function() {
$('<img>', { src: '/image.jpg' }).appendTo(this);
});
});
This is fine if the script runs before the animation completes and the animationend
event fires, but if the script happens to run after the animation ends the <img>
tag will never be created and will never be appended to the div (for example if the handler was set in a timeout or something like that which ran past the animation duration).
Is there any way to detect if a CSS animation is currently running so the script can decide whether to wait for the animationend
or not without having to rely on user added classes or data attributes?
(I ask to not rely on classes and attributes because if I'm working with someone else's animations I may not know the classes ahead of time)
Any help would be appreciated.
Why not just using .on()
on the document and even check which animation has just
finished and which element was animated (e.target
) The event handler will attached before the DOM is fully loaded and CSS animation are fired.
DEMO: JSnippet Demo
Note: do not attach when DOM ready - $(function(){ ... })
$(document).on([
'webkitAnimationEnd',
'mozAnimationEnd',
'MSAnimationEnd',
'oanimationend',
'animationend'
].join(' '), function(e) {
//Do whatever you want
console.log(e);
$('ul').append(
"<li>Animation end detected on: "
+ e.target
+ "." + e.target.className +
"</li>"
);
});
$(function(){
$('button').click(function(){
$(this).addClass('animate');
});
});
$(document).on([
'webkitAnimationEnd',
'mozAnimationEnd',
'MSAnimationEnd',
'oanimationend',
'animationend'
].join(' '), function(e) {
//Do whatever you want
console.log(e);
$('ul').append(
"<li>Animation end detected on: "
+ e.target
+ "." + e.target.className +
"</li>"
);
$('button').removeClass('animate');
});
button {
width: 300px;
background-color: red;
}
button.animate {
-webkit-animation-name: example; /* Chrome, Safari, Opera */
-webkit-animation-duration: 1s; /* Chrome, Safari, Opera */
animation-name: example;
animation-duration: 1s;
}
/* Chrome, Safari, Opera */
@-webkit-keyframes example {
from {background-color: red;}
to {background-color: yellow;}
}
/* Standard syntax */
@keyframes example {
from {background-color: red;}
to {background-color: yellow;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<button class="animate">Trigger animation</button>
<ul></ul>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With