Opera 12 oTransitionEnd Bugs and Workarounds
Toward the end of April I wrote up my concerns about Opera rendering Webkit prefixed properties and provided several code examples of how that could cause issues for developers. The debate about Opera rendering Webkit seems to have died down and Opera hasn't said anything much beyond their initial announcement. As yet, the idea hasn't gone beyond the experimental Opera Mobile Emulator.
This post isn't about Opera rendering Webkit prefixed properties but instead the issues I didn't expect to find in the main release Opera browsers whilst testing the experimental Opera Mobile Emulator. These are issues that have existed in Opera for a while and have gotten worse in the newly released Opera 12.
oTransitionEnd and other Event Names Changed to Lowercase
Update 20/06/2012: It appears that Opera intentionally changed oTransitionEnd to lowercase. oTransitionEnd is obviously supported to try and save backwards compatibility but the issue mentioned below -- using oTransitionEnd doesn't work via jQuery -- still stands.
I've been unable to find the official transitionEnd event to use for Opera on the Dev.Opera website but Mozilla suggest the event name is oTransitionEnd and the Opera post about the experimental Opera Mobile Emulator suggests the same. When binding oTransitionEnd
in Opera 11, as you'd expect, an event is fired when a transition ends.
In Opera 12, when binding oTransitionEnd
via standalone JavaScript, an event is triggered (actually six are but more on that later):
document.addEventListener("oTransitionEnd", function(){
alert("Transition Ended");
});
When binding oTransitionEnd via jQuery though, nothing happens:
$(document).bind("oTransitionEnd", function(){
alert("Transition Ended");
});
This got me scratching my head. If standalone JavaScript binds the event then why won't jQuery? I then made the event return what type of event was being triggered:
document.addEventListener("oTransitionEnd", function(e){
alert(e.type);
});
Did it return oTransitionEnd
? No. It returned otransitionend
, all in lowercase.
By using the lowercase otransitionend
, you can get an event to fire:
$(document).bind("otransitionend", function(){
alert("Transition Ended");
});
This means you can workaround the issue and write a transitionEnd event that works in Opera 12 and earlier versions using both the camelcase oTransitionEnd
and lowercase otransitionend
:
$(document).bind("oTransitionEnd otransitionend", function(){
alert("Transition Ended");
});
However, any existing scripts without the lowercase otransitionend
will not work in Opera 12. It's possible jQuery could be updated to fix this in Opera 12 but leaves existing scripts without backwards compatibility.
This also happens for oAnimationEnd
.
transitionEnd Events Fire Six Times
Yup, six! In Opera 11, the transitionEnd event fired twice for every one transition ending. In Opera 12, a transitionEnd event will fire six times whether binding via JavaScript or jQuery.
However, when testing using animationEnd events, only one was triggered for each animation ending.
If this is an issue for you, you can unbind the otransitionend
event once it's fired, like so:
$(document).bind("otransitionend", function(){
$(this).unbind("otransitionend");
alert("Transition Ended");
});
Summary
Of course, whilst there are workarounds for these issues, it'd be better if they weren't needed. Having to use prefixed events, along with prefixed properties is enough work as it is.
Ian Lunn is a Front-end Developer with 12 years commercial experience, author of CSS3 Foundations, and graduate of Internet Technology. He creates successful websites that are fast, easy to use, and built with best practices.