14

I'd like to delete an object after it's done animating with a CSS transition, but I'm not able to use a JavaScript library.

How do I detect when the animation is done? Do I use a callback or custom event somehow?

Matt Norris
  • 8,596
  • 14
  • 59
  • 90

3 Answers3

18
element.addEventListener('transitionend', function(event) {
    alert("CSS Property completed: " + event.propertyName);
}, false );

For now, the exact event name has not been standardized. Here's a quote from MDN:

There is a single event that is fired when transitions complete.
In all standard-compliant browser, the event is transitionend,
in WebKit it is webkitTransitionEnd.

Here's the fiddle for Webkit: http://jsfiddle.net/bNgWY/

Joseph Silber
  • 214,931
  • 59
  • 362
  • 292
  • How do I assign this to a particular transition, like opacity? – Matt Norris Jan 11 '12 at 05:41
  • @Wraith - You cannot assign it to a particular transition. Rather, you listen to the event firing on the element. You can then get the information you are looking for from the event object. See my update. – Joseph Silber Jan 11 '12 at 05:47
  • 1
    @Wraith: Look for "Detecting the completion of a transition" on the page Joseph linked to. `propertyName`: A string indicating the name of the CSS property whose transition completed. `elapsedTime`: A float indicating the number of seconds the transition had been running at the time the event fired. This value isn't affected by the value of transition-delay . – Ruan Mendes Jan 11 '12 at 05:47
4

As I'm currently doing the exact same thing I'll share a useful, cross-browser implementation from a Marakana tutorial.

   // First, we store the names of the event according to the browsers
            
   var navigatorsProperties=['transitionend','OTransitionEnd','webkitTransitionEnd'];

            //For each of them...
            for (var i in navigatorsProperties) {
                //We attach it to our overlay div
                el.addEventListener(navigatorsProperties[i],function()
                {
                    // Here's the code we want to fire at transition End
                      console.log('transition end');

                },false);
            }

It's to be noted that IE10 supports transitions with transitionend (see MSDN).

IE9 and below do not support transitions (see caniuse.com ) so you won't be able to attach any eventListener to a transition end ( so don't try msTransitionend or whatever for those browsers).

EDIT: While reading Modernizr documentation on Github I stumbled on their cross-browser polyfills page. Among many other useful links I found this small but extremely good transitionend script.

Mind that the examples in the Github README.md use jQuery but the library indeed requires no libraries and no dependencies as it's written in vanilla javascript.

Aurelio
  • 24,702
  • 9
  • 60
  • 63
1

I was unable to find a suitable 'transitionend' polyfill that met my requirements. So if you want something for hooking the transition end once, use this:

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

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

    Object.prototype.onTransitionEndOnce = function(callback) {
        if (transitionEnd === '') {
            callback();
            return this;
        }
        var transitionEndWrap = function(e) {
            callback(); 
            e.target.removeEventListener(e.type, transitionEndWrap);
        };
        this.addEventListener(transitionEnd, transitionEndWrap);
        return this;
    };
}());
SilbinaryWolf
  • 461
  • 4
  • 9