Detecting transition event support

PPK’s mantra, There is no WebKit on Mobile, has been ringing in my ears since I recently started working on a mobile site targeted towards iPhone 3+, Android 1.5+, and webOS 1.3+.

iPhone 3, Android 1.5, and webOS 1.3 all support easy-peasy CSS-based animations with -webkit-transition, but there’s a big gap with the implementation on webOS.

When an element’s transition has completed (or otherwise been stopped), a transition end event is supposed to be dispatched by the element, like so:

<div id="foo">Foo</div>
#foo {opacity:1;-webkit-transition:opacity 1s linear;}
var foo = document.getElementById('foo');
foo.addEventListener('webkitTransitionEnd', function(e) {
this.parentNode.removeChild(this);
}, false);
foo.style.opacity = '0';
foo = null;

The above code removes a DIV from the DOM after it finishes fading out. Pretty typical situation.

The problem is that, in webOS, the element does not dispatch the webkitTransitionEnd event when the animation has completed.

Here’s a snippet of code that you can use to detect whether or not a browser supports the transition end event:

var transitionEndSupported = false,
transitionEndEventTypeName = null;
(function() {
if (window.addEventListener) {
var div = document.createElement('div'),
handler = function(e) {
transitionEndEventTypeName = e.type;
transitionEndSupported = true;
this.removeEventListener('webkitTransitionEnd', arguments.callee);
this.removeEventListener('transitionend', arguments.callee);
};
div.setAttribute('style', 'position:absolute;top:0px;transition:top 1ms ease;-webkit-transition:top 1ms ease;-moz-transition:top 1ms ease');
div.addEventListener('webkitTransitionEnd', handler, false);
div.addEventListener('transitionend', handler, false);
document.documentElement.appendChild(div);
setTimeout(function() {
div.style.top = '100px';
setTimeout(function() {
div.parentNode.removeChild(div);
div = handler = null;
}, 100);
}, 0);
}
})();

After this code has finished running, transitionEndSupported will indicate whether or not the transition end event supported. As an added bonus, you can use this method to detect the name of the transition end event (webkitTransitionEnd for WebKit browsers, transitionend for Gecko).

In browsers that don’t properly support the transition end event, you can use setTimeout to achieve roughly the same effect, albeit not synced precisely to the animation.

No comments.

Leave a Reply