I'm looking for a cleaner way to feature detect the actual name of the transitionend
. I've seen a lot of examples just brute force adding handlers to all the variations. Also, I don't want to have to rely on jQuery (or similar framework).
I'm basically starting with this list and hoping to just bind the best fit (i.e., first in list to match).
var transitionendName,
events = [
'transitionend',
'webkitTransitionEnd',
'MozTransitionEnd',
'oTransitionEnd'
];
// ^^^^^ your code here
myElem.addEventListener(transitionendName, myHandler, false);
Anyone feel they have a clean solution to this? The same solution presumably will work for animationend
events.
Edit: msTransitionEnd and '-ms-' prefixed properties were removed in one of the final IE10 release candidates.
You can register all the event end names and then trigger a very short CSS transition and see which one fires. Also, IE10, uses transitionend
, so there is no browser that uses msTransitionEnd
.
Here's an example of how to do that: http://jsfiddle.net/jfriend00/5Zv9m/
var transitionendName,
events = [
'transitionend',
'webkitTransitionEnd',
'MozTransitionEnd',
'oTransitionEnd'
];
function findTransitionEnd(callback) {
// add an off-screen element
var elem = document.createElement("div");
elem.id = "featureTester";
document.body.appendChild(elem);
// clean up temporary element when done
function cleanup() {
document.body.removeChild(elem);
elem = null;
}
// set fallback timer in case transition doesn't trigger
var timer = setTimeout(function() {
if (!transitionendName) {
cleanup();
callback("");
}
}, 200);
// register all transition end names
for (var i = 0; i < events.length; i++) {
(function(tname) {
elem.addEventListener(tname, function() {
if (!transitionendName) {
transitionendName = tname;
clearTimeout(timer);
cleanup();
callback(tname);
}
});
})(events[i]);
}
// trigger transition
setTimeout(function() {
elem.className = "featureTestTransition";
}, 1);
}
Another variation which qualifies for pure feature detection (rather than a purely pragmatic solution) but is more efficient:
var transitionendNames = [
'transitionend',
'webkitTransitionEnd',
'MozTransitionEnd',
'oTransitionEnd'
];
/**
* Helper function to bind to the correct transitionend event
* @param {function} callback The function to call when the event fires
*/
var transitionend = function(elem, callback) {
var handler = function(e) {
//console.log('transitionend == '+e.type);
// test in case multiple were registered before change
if (transitionendNames) {
// store the actual name
var transitionendName = e.type;
// every other time, bind only to actual event
transitionend = function(elem, callback) {
elem.addEventListener(transitionendName, callback, false);
};
// flag for any others
transitionendNames = null;
}
return callback.call(elem, e);
};
// until an event has been triggered bind them all
for (var i=0, len=transitionendNames.length; i<len; i++) {
elem.addEventListener(transitionendNames[i], handler, false);
}
};
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With