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");
});

JSFiddle Demo Here

When binding oTransitionEnd via jQuery though, nothing happens:

$(document).bind("oTransitionEnd", function(){
    alert("Transition Ended");
});

JSFiddle Demo Here

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);
});

JSFiddle Demo Here

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");
});

JSFiddle Demo Here

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");
});

JSFiddle Demo Here

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.

Useful? Buy me a coffeeUseful? Buy me a coffee

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.