Detecting CSS Animation Completion with JavaScript

One fact of web development life in 2014 that's been difficult for me to admit is that the traditional JavaScript toolkit is mostly dead.  For years we relied on them for almost everything but now that JavaScript and CSS has caught up with what we need, we can often avoid using JavaScript toolkits if we take the time to research new native capabilities.  One argument for sticking with toolkits that I often hear is that CSS animations don't provide callback abilities.

Wrong.  False.  Incorrect.  ┬┐Que?  JavaScript does provide us the ability to trigger functionality at the end of JavaScript animations and transitions. Here's how!

The only reason this is a somewhat involved task at this point is the need to account for browser prefixes.  The transitionend event and animationend is what standardized browsers require but WebKit-based browsers still rely on prefixes so we have to determine the prefix for the event, then apply it:

/* From Modernizr */
function whichTransitionEvent(){
    var t;
    var el = document.createElement('fakeelement');
    var transitions = {
      'transition':'transitionend',
      'OTransition':'oTransitionEnd',
      'MozTransition':'transitionend',
      'WebkitTransition':'webkitTransitionEnd'
    }

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

/* Listen for a transition! */
var transitionEvent = whichTransitionEvent();
transitionEvent && e.addEventListener(transitionEvent, function() {
	console.log('Transition complete!  This is the callback, no library needed!');
});

/*
	The "whichTransitionEvent" can be swapped for "animation" instead of "transition" texts, as can the usage :)
*/

Once the animation or transition ends, the callback fires.  No need for a big library to assign callbacks to animations anymore!

Imageine how much in JavaScript code you can save by avoiding a JavaScript library for this.  The duration, fill-mode, and delay can all be set via CSS, so your JavaScript stays lightweight.  Major win!