Callback on CSS transition

60,187

Solution 1

I know that Safari implements a webkitTransitionEnd callback that you can attach directly to the element with the transition.

Their example (reformatted to multiple lines):

box.addEventListener( 
     'webkitTransitionEnd', 
     function( event ) { 
         alert( "Finished transition!" ); 
     }, false );

Solution 2

Yes, if such things are supported by the browser, then an event is triggered when the transition completes. The actual event however, differs between browsers:

  • Webkit browsers (Chrome, Safari) use webkitTransitionEnd
  • Firefox uses transitionend
  • IE9+ uses msTransitionEnd
  • Opera uses oTransitionEnd

However you should be aware that webkitTransitionEnd doesn't always fire! This has caught me out a number of times, and seems to occur if the animation would have no effect on the element. To get around this, it makes sense to use a timeout to fire the event handler in the case that it's not been triggered as expected. A blog post about this problem is available here: http://www.cuppadev.co.uk/the-trouble-with-css-transitions/ <-- 500 Internal Server Error

With this in mind, I tend to use this event in a chunk of code that looks a bit like this:

var transitionEndEventName = "XXX"; //figure out, e.g. "webkitTransitionEnd".. 
var elemToAnimate = ... //the thing you want to animate..
var done = false;
var transitionEnded = function(){
     done = true;
     //do your transition finished stuff..
     elemToAnimate.removeEventListener(transitionEndEventName,
                                        transitionEnded, false);
};
elemToAnimate.addEventListener(transitionEndEventName,
                                transitionEnded, false);

//animation triggering code here..

//ensure tidy up if event doesn't fire..
setTimeout(function(){
    if(!done){
        console.log("timeout needed to call transition ended..");
        transitionEnded();
    }
}, XXX); //note: XXX should be the time required for the
        //animation to complete plus a grace period (e.g. 10ms) 

Note: to get the transition event end name you can use the method posted as the answer in: How do I normalize CSS3 Transition functions across browsers?.

Note: this question is also related to: - CSS3 transition events

Solution 3

I am using the following code, is much simpler than trying to detect which specific end event a browser uses.

$(".myClass").one('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', 
function() {
 //do something
});

Alternatively if you use bootstrap then you can simply do

$(".myClass").one($.support.transition.end,
function() {
 //do something
});

This is becuase they include the following in bootstrap.js

+function ($) {
  'use strict';

  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
  // ============================================================

  function transitionEnd() {
    var el = document.createElement('bootstrap')

    var transEndEventNames = {
      'WebkitTransition' : 'webkitTransitionEnd',
      'MozTransition'    : 'transitionend',
      'OTransition'      : 'oTransitionEnd otransitionend',
      'transition'       : 'transitionend'
    }

    for (var name in transEndEventNames) {
      if (el.style[name] !== undefined) {
        return { end: transEndEventNames[name] }
      }
    }

    return false // explicit for ie8 (  ._.)
  }

  // http://blog.alexmaccaw.com/css-transitions
  $.fn.emulateTransitionEnd = function (duration) {
    var called = false, $el = this
    $(this).one($.support.transition.end, function () { called = true })
    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
    setTimeout(callback, duration)
    return this
  }

  $(function () {
    $.support.transition = transitionEnd()
  })

}(jQuery);

Solution 4

This can easily be achieved with the transitionend Event see documentation here A simple example:

document.getElementById("button").addEventListener("transitionend", myEndFunction);

function myEndFunction() {
	this.innerHTML = "Transition event ended";
}
#button {transition: top 2s; position: relative; top: 0;}
<button id="button" onclick="this.style.top = '55px';">Click me to start animation</button>

Solution 5

The jQuery.transit plugin, a plugin for CSS3 transformations and transitions, can call your CSS animations from script and give you a callback.

Share:
60,187

Related videos on Youtube

Pompair
Author by

Pompair

Updated on January 07, 2022

Comments

  • Pompair
    Pompair over 2 years

    Is it possible to get a notification (like callback) when a CSS transition has been completed?

  • Katya Appazova
    Katya Appazova about 13 years
    is there the same thing for other browser then webkit?
  • qqryq
    qqryq about 13 years
    yes, 'transitionend' for Mozilla & 'oTransitionEnd' in Opera.
  • Katya Appazova
    Katya Appazova about 13 years
    what does the false at the end do?
  • Doug Neiner
    Doug Neiner about 13 years
    @meo It has something to do with the this element inside the callback. But its a required parameter, so in this case its just fulfilling the requirement.
  • rybosome
    rybosome over 11 years
    @DougNeiner The false at the end is for useCaptureMode. When an event occurs, there are two phases - the first phase is capture mode, the second is bubble mode. In capture mode, the event descends from the body element to the specified element. It then enters bubble mode, where it does the reverse. That final false param specifies that you want the event listener to occur in bubble mode. One use of this is to attach event handlers right before they are needed in bubble mode. =) 37signals.com/svn/posts/…
  • Wes
    Wes almost 11 years
    This is a much fuller answer than the accepted one. Why isn't this more upvoted.
  • phreakhead
    phreakhead about 10 years
    This is slower because it has to search through that entire list each time the event happens to see if it is the correct one.
  • Tom
    Tom almost 10 years
    @phreakhead The performances of any of these approaches will be very similar
  • Miquel
    Miquel about 9 years
    Remember to call transitionEndedHandler in transitionEnded (or change transitionEnded by transitionEndedHandler in addEventListener and removeEventListener and call transitionEnded in transitionEndedHandler)
  • Mark Rhodes
    Mark Rhodes about 9 years
    Thanks @Miquel; think I'd just used transitionEnded when I meant transitionEndedHandler.
  • danwellman
    danwellman about 9 years
    It's only a required parameter in Firefox I believe
  • Willster
    Willster almost 9 years
    I believe the Chromium issue for this can be found here: code.google.com/p/chromium/issues/detail?id=388082 Although, the last comment seems to (incorrectly in my view) discount it as a bug and therefore it is currently marked as "won't fix".
  • Ruan Mendes
    Ruan Mendes about 4 years
    No need for different names nowadays caniuse.com/#feat=css-transitions
  • Ruan Mendes
    Ruan Mendes about 4 years
    This is the correct answer nowadays, there's no need to have prefixes anymore. caniuse.com/#feat=css-transitions

Related