Given the following:
.slide{
transition: all 1s ease 0s;
transform: translateX(-100%);
}
and
document.documentElement.addEventListener('animationstart', function() {
alert(1);
}, false);
the event won't fire.
However, if the CSS is :
.slide {
animation: slide 1s infinite
}
@keyframes slide {
from {
transform: translateX(0);
}
to {
transform: translateX(-100px);
}
}
It does fire.
How come? It's an animation in both cases, however, in the first case we don't use the keyframes which have other negative consequences.
Isn't this an error in how browsers have implemented this feature?
Here is an example for the first:
http://jsbin.com/hizoyopimu/1/edit?html,css,js,console,output
And second:
http://jsbin.com/yegidehusi/1/edit?html,css,js,console,output
Is there something equivalent?
TL;DR (Short Answer):
As of now there is no event that gets fired during the start of a transition. Transitions always happen only when a triggering condition is satisfied and so the event which triggers the transition can roughly be considered as equivalent to the transitionstart
event.
In the below snippet, I have added a user-defined function (transitionStart
) which gets called right after the .addClass('slide')
and this is kind of equivalent to transitionstart
.
/* For Animation Start */
setTimeout(function() {
$('.animated').removeClass('hide').addClass('slide');
}, 1000);
$('.animated').bind('animationstart webkitAnimationStart', function() {
console.log('Animation Started');
});
/* For Transition Start */
setTimeout(function() {
$('.animated').removeClass('hide').addClass('slide');
transitionStart();
}, 1000);
function transitionStart(){
console.log('Transition Started');
}
.element {
padding: 10px;
background-color: #ccc;
width: 100px;
height: 100px;
}
.element.animated.hide {
display: none;
}
.animated.slide {
animation: slide 1s infinite
}
@keyframes slide {
from {
transform: translateX(0);
}
to {
transform: translateX(-100px);
}
}
.element.transitioned.hide {
transform: translateX(-100%);
}
.transitioned.slide {
transition: all 2s ease-in 0s;
transform: translateX(200%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>Element with Animation</h3>
<div class='element hide animated'>
box
</div>
<h3>Element with Transition</h3>
<div class='element hide transitioned'>
box
</div>
A transitionend
event is available and can be used to identify the ending point of the transition and then perform any required function calls or other process. The below snippet has a sample for this.
setTimeout(function() {
$('.transitioned').removeClass('hide').addClass('slide');
transitionStart();
}, 1000);
function transitionStart(){
console.log('Transition Started');
}
$('.transitioned').bind('transitionend', function() {
console.log('Transition Ended');
});
.element {
padding: 10px;
background-color: #ccc;
width: 100px;
height: 100px;
}
.element.transitioned.hide {
transform: translateX(-100%);
}
.transitioned.slide {
transition: all 2s ease-in 0s;
transform: translateX(200%);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<h3>Element with Transition</h3>
<div class='element hide transitioned'>
box
</div>
Long Answer:
First of all, animation
and transition
are not same even though they produce a gradual change of the values assigned to the properties. Below are some key differences:
hover
, click
etc) or when some extra class is added to the element through JS. Animations can start automatically when the page is loaded.You can read more about the differences between them and when one should be used in this article.
Animation events (animationstart
, animationend
etc) will not fire for your first case (the one where you are using transition
) because there is no animation
or valid @keyframe
rule specified on the element.
As per W3C Spec
Any animation for which both a valid keyframe rule and a non-zero duration are defined will run and generate events; this includes animations with empty keyframe rules.
As per current spec there is no specific event that is fired when a transition
is started unlike when an animation
starts. In other words, there is no transitionstart
event. Currently there is only one transition event (transitionend
) that is implemented. (W3C Spec).
I cannot say for sure if it was a conscious decision to not implement transitionstart
event or it was just a miss. But the fact is that we don't have an equivalent one at present.
Personally, I do not see this as a big miss because the developer should know the exact trigger points for a transition
(like the addition of a new class via JS or through user interaction events which can also be detected via JS). So, we can always say that a transition has started at the very same instant when the trigger condition was satisfied. For your case, the transition
has started at the same time at which the .addClass('slide')
is executed. So, whatever extra steps you want to do (or) functions that you want to call can be called directly after the .addClass('slide')
is executed.
Points to note:
animationstart
event. The reason is because the animationstart
event is fired only after the animation-delay
that is set has expired. In your snippet there is no delay for either the animation or transition and hence this is not a big issue. If you do have a delay then you'd have to get the value of the transition-delay
property and execute another time-out before calling the required functions (or) actions.transitionstart
event but it is non-standard and hence is not recommended.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