Detectar fin de una transici贸n/animaci贸n CSS3 con Javascript

Tiempo de lectura: 2 min

Nunca me hab铆a visto en la necesidad de detectar cuando una transici贸n CSS3 termina, pero el otro d铆a en el trabajo, para desplegar cierta informaci贸n, estamos utilizando 2 contenedores, y al a帽adir una clase se activa una animaci贸n CSS3 que va aumentando el margen izquierdo del div hasta que aparece el siguiente. Para ello estamos utilizando eventos de teclado, si pulsamos flecha derecha va hacia la derecha, en caso de pulsar la flecha izquierda, hacia la izquierda, muy sencillito.

驴Y qu茅 pasa si pulsamos varias veces antes de que la animaci贸n termine? Pues que parece que va a tirones, y lo que es un efecto de transici贸n muy elegante se convierte en un efecto muy desagradable. No estaba al tanto, pero cuando un elemento presenta una animaci贸n puramente en CSS3, en funci贸n del navegador, podemos suscribirnos a un evento que nos informar谩 cuando la transici贸n ha terminado. En este proyecto estamos utilizando jQuery, asi que la soluci贸n es bien sencilla:

Soluci贸n para transiciones:

var ended = false;
$("#selector").bind("transitionend
                     webkitTransitionEnd 
                     oTransitionEnd 
                     MSTransitionEnd", function(){ 
                        ended = true;
                    });

Soluci贸n para animaciones:

var ended = false;
$("#someSelector").bind("animationend 
                         webkitAnimationEnd 
                         oAnimationEnd 
                         MSAnimationEnd", function(){
                        ended = true;
                    });

Si no deseas usar jQuery, en Modernizr tienen esto:

function transitionEndEventName () {
    var i,
        undefined,
        el = document.createElement('div'),
        transitions = {
            'transition':'transitionend',
            'OTransition':'otransitionend',  // oTransitionEnd in very old Opera
            'MozTransition':'transitionend',
            'WebkitTransition':'webkitTransitionEnd'
        };

    for (i in transitions) {
        if (transitions.hasOwnProperty(i) && el.style[i] !== undefined) {
            return transitions[i];
        }
    }

    //TODO: throw 'TransitionEnd event is not supported in this browser'; 
}

Y se utiliza de la siguiente manera:

var transitionEnd = transitionEndEventName();
element.addEventListener(transitionEnd, theFunctionToInvoke, false);

Encontr茅 la soluci贸n en StackOverflow: