I'm implementing an excellent solution (found here) to use a callback function a la jQuery when using CSS transitions.
The problem is that if I use vendor prefixes, Chrome at least binds two events: one for webkitTransitionEnd and the second one for transitionend and, of course, fires the callback twice. Here's my piece of code:
jQuery("#main").one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(e) {
console.log("POUM!");
});
Am I doing something wrong?
You're not doing anything wrong. Chrome just uses both the prefixed and un-prefixed versions.
There are a couple options:
Using an outside variable.
var fired = false;
jQuery("#main").one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(e) {
if ( ! fired ) {
fired = true;
console.log("POUM!");
}
});
Using some kind of detection to get a single variable for transitionend (the below uses Modernizr, and is taken from their documentation):
var transitionend = (function(transition) {
var transEndEventNames = {
'WebkitTransition' : 'webkitTransitionEnd',// Saf 6, Android Browser
'MozTransition' : 'transitionend', // only for FF < 15
'transition' : 'transitionend' // IE10, Opera, Chrome, FF 15+, Saf 7+
};
return transEndEventNames[transition];
})(Modernizr.prefixed('transition'));
// then
jQuery("#main").one(transitionend, function(e) {
console.log("POUM!");
});
NOTE:
Safari 6 seems to trigger onload
for anything that is set in the CSS. So, if you have (assuming all prefixes)
#main {
width: 40px;
height: 40px;
transition: all 200ms;
}
Safari will trigger the transitionend
with width
and height
on load. There are a couple ways to get around this:
Do the following in javascript (it's not the prettiest thing, but it should take care of that edge case and it still works in Chrome) fiddle
var transitionProperty = 'background-color',
startColor = jQuery("#main").on(transitionend, function(e) {
var el = $(this);
if ( transitionProperty === e.originalEvent.propertyName && el.css(transitionProperty) !== startColor ) {
console.log("POUM!");
// This is to make it only happen once.
$(this).off(transitionend);
}
}).css(transitionProperty);