Reputation: 6664
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
Reputation: 145880
CSS animations have different callbacks.
Here's the callbacks for animation:
$(document).one("animationend webkitAnimationEnd oAnimationEnd MSAnimationEnd",
"#robot",
function (event)
{
// complete
});
Upvotes: 20
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
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