xyhhx
xyhhx

Reputation: 6664

TransitionEnd Event not firing?

I have multiple elements that are animating at a (somewhat) duration each. I'm animating using CSS3 transitions, using the jQuery library and a transitionend helper function from David Walsh.

My issue is that the transitionEnd event is NOT being fired! (In Chrome & Firefox)

My code:

var $children = $container.find('.slideblock').children();

if(Modernizr.csstransitions && Modernizr.csstransforms3d) {

    if($.browser.webkit === true) {
        $children.css('-webkit-transform-style','preserve-3d')
    }

    $children.each(function(i){
        $(this).on(whichTransitionEvent,function () {
            $(this).remove();
        });
        $(this).show().css('animation','slideOutToRight ' + ((Math.random() / 2) + .5) + 's');
    });

}

Update

The whichTransitionEvent variable points to a self-executing function that returns a string containing the event name:

var whichTransitionEvent = (function (){
    var t;
    var el = document.createElement('fakeelement');
    var transitions = {
      'transition'       :'transitionEnd',
      'OTransition'      :'oTransitionEnd',
      'MSTransition'     :'msTransitionEnd',
      'MozTransition'    :'transitionend',
      'WebkitTransition' :'webkitTransitionEnd'
    }

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

console.log(whichTransitionEvent);        // returns "webkitTransitionEvent" in Chrome
console.log(typeof whichTransitionEvent); // returns "string"

Upvotes: 9

Views: 23832

Answers (3)

Simon_Weaver
Simon_Weaver

Reputation: 145880

Don't confuse 'transitions' with 'animations'.

CSS animations have different callbacks.

Here's the callbacks for animation:

 $(document).one("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd", 
                "#robot", 
    function (event)
    {
        // complete
    });

Upvotes: 20

James Ramirez
James Ramirez

Reputation: 116

Attempting to replicate this in Chrome 29 and Firefox 23, your original function failed in the same way, i.e. I'm seeing console.log(whichTransitionEvent) returning 'transitionEnd' for both.

Re-ordering the elements within the transitions hash fixes the issue, suggesting both have the unprefixed standards property as well as their own prefixed one.

Refactored function below, which fires the correct events for me:

function whichTransitionEvent(){
  var t;
  var el = document.createElement('fakeelement');
  var transitions = {
    'WebkitTransition' :'webkitTransitionEnd',
    'MozTransition'    :'transitionend',
    'MSTransition'     :'msTransitionEnd',
    'OTransition'      :'oTransitionEnd',
    'transition'       :'transitionEnd'
  }

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

Let me know if this helps

Upvotes: 8

methodofaction
methodofaction

Reputation: 72385

You are passing a function instead of a string, so you're doing the equivalent of...

$(this).on(function(){...}, function() {...})

To fix this I'd recommend setting the string at the beginning of your script, so it doesn't get called multiple times.

if(Modernizr.csstransitions && Modernizr.csstransforms3d) {
    var transitionEnd = whichTransitionEvent();
    if($.browser.webkit === true) {
        $children.css('-webkit-transform-style','preserve-3d')
    }

    $children.each(function(i){
        $(this).on(transitionEnd,function () {
            $(this).remove();
        });
        $(this).show().css('animation','slideOutToRight ' + ((Math.random() / 2) + .5) + 's');
    });

}

Upvotes: -1

Related Questions