Il DOM dispone di tre eventi specifici che possiamo usare per monitorare le animazioni CSS. Un inizio (animationstart
), una fine
(animationend
) ed una ripetizione (animationiteration
). Il problema è che attualmente i browser implementano questi
eventi attraverso i loro prefissi proprietari.
Per prima cosa definiamo una semplice animazione:
@-webkit-keyframes move {
0% {
left: 100px;
}
50% {
width: 150px;
height: 150px;
}
100% {
width: 100px;
height: 100px;
left: 0;
}
}
@-moz-keyframes move {
0% {
left: 100px;
}
50% {
width: 150px;
height: 150px;
}
100% {
width: 100px;
height: 100px;
left: 0;
}
}
@-ms-keyframes move {
0% {
left: 100px;
}
50% {
width: 150px;
height: 150px;
}
100% {
width: 100px;
height: 100px;
left: 0;
}
}
@keyframes move {
0% {
left: 100px;
}
50% {
width: 150px;
height: 150px;
}
100% {
width: 100px;
height: 100px;
left: 0;
}
}
.animate {
-webkit-animation: move 2s ease-in 2s 3 alternate;
-moz-animation: move 2s ease-in 2s 3 alternate;
-ms-animation: move 2s ease-in 2s 3 alternate;
animation: move 2s ease-in 2s 3 alternate;
}
Quindi definiamo una funzione di utility per uniformare i nomi degli eventi nei vari browser:
var prefixes = [ 'webkit', 'moz', 'MS', 'o', '' ];
var prefixedEvent = function( element, type, callback ) {
for ( var p = 0; p < prefixes.length; p++ ) {
if ( !prefixes[p] ) {
type = type.toLowerCase();
}
element.addEventListener( prefixes[p] + type, callback, false );
}
}
A questo punto possiamo creare un unico handler che andrà ad eseguire un'azione diversa in base al tipo di evento:
var animationHandler = function( e ) {
var item = document.createElement( 'li' ),
evtType = e.type,
evtStr = evtType.toLowerCase();
if( evtStr.indexOf( 'start' ) != - 1 ) {
item.innerHTML = 'Event started at time ' + e.elapsedTime;
}
if( evtStr.indexOf( 'end' ) != - 1 ) {
item.innerHTML = 'Event ended at time ' + e.elapsedTime;
}
if( evtStr.indexOf( 'iteration' ) != - 1 ) {
item.innerHTML = 'Now entering the loop at time ' + e.elapsedTime;
}
document.getElementById( 'log' ).appendChild( item );
};
Il codice finale sarà il seguente:
document.addEventListener( 'DOMContentLoaded', function() {
var test = document.getElementById( 'test' );
var run = document.getElementById( 'run' );
prefixedEvent( test, 'AnimationStart', animationHandler );
prefixedEvent( test, 'AnimationEnd', animationHandler );
prefixedEvent( test, 'AnimationIteration', animationHandler );
run.addEventListener( 'click', function() {
test.className = 'animate';
}, false );
}, false );