I’ve run into an interesting case that isn’t explicitly covered in the W3C CSS Transitions spec or the MDN CSS Transitions doc that I thought I would share because it cost me a bit of time.
If you “change” a CSS transitioned property to the same value then no transitioned event is fired. As I think about I can see why this would be the default behavior, but it can easily cause issues for the unsuspecting developer with something like this:
$("#test").css("opacity", "1").bind("transitionend", doneFn);
In the above code, if the element in question happens to have a opacity of 1 then the doneFn will never be called. Also see http://jsfiddle.net/studgeek/Xj8TB/.
To make this is a question, is there a good workaround for handling this?
You could compare the property value to the existing property value to the existing property value but that is trickier than it sounds to do it well because css property values can take so many forms – different units, and even string values like auto. So you really have to test the objects actual state, which of course needs to be done different for each property. Ugh.
One work-around would be to make your own jQuery method for setting a CSS value that would handle everything for you. It would get the current value of the property, set the new value, check to see if the value had changed. If it had not, then it would fire the completion function manually:
In your example above, it would work like this:
Working example here: http://jsfiddle.net/jfriend00/LHdGR/
This plug-in could be expanded to support passing a map of multiple properties like the
.css()supports too.The only other option I can think of is to read the transtionDuration and set a timeout value for slightly longer than that. If the transitionEnd event fires, you cancel the timeout. If it doesn’t fire, the timeout can manually fire the transitionEnd event. The code for this could work like this:
Working example here: http://jsfiddle.net/jfriend00/hxevW/