admin管理员组文章数量:1289515
The list of properties that can be animated with a CSS3 transition is not consistent among browsers and is a subject to change with new browser versions. For example, -moz-transform is not animatable with -moz-transition in FF3.6 but it is in FF4.
So, is there a way to detect in JavaScript if a particular property is animatable? I wouldn't like to use user agent sniffing as it's not reliable.
Thanks in advance!
The list of properties that can be animated with a CSS3 transition is not consistent among browsers and is a subject to change with new browser versions. For example, -moz-transform is not animatable with -moz-transition in FF3.6 but it is in FF4.
So, is there a way to detect in JavaScript if a particular property is animatable? I wouldn't like to use user agent sniffing as it's not reliable.
Thanks in advance!
Share Improve this question asked Jan 13, 2011 at 10:59 MournerMourner 3,29127 silver badges21 bronze badges 1- 2 @Mourner It would be rad if you could unaccept my answer and accept Jordan's, just for people googling this kind of stuff. – methodofaction Commented Jun 29, 2012 at 15:31
2 Answers
Reset to default 10Yes, there is a way. Demonstration follows, explanation below. There are some very important caveats involved, so make sure you read on.
The following code will test if the browser can animate between two values.
The code
jsFiddle demo.
/*
@param property The property to test.
@param from A valid starting value for the animation.
@param to A valid ending value for the animation.
@param [element] The element to test with. (Required for testing
properties with prerequisites, e.g. "top" requires
non-static position.)
*/
function isAnimationSupported(property, from, to, element) {
var doc = document.documentElement,
style = doc.appendChild(document.createElement("style")),
rule = [
'capTest{',
'0%{', property, ':', from, '}',
'100%{', property, ':', to, '}',
'}'
].join(''),
propCamel = property.toCamelCase(),
prefixes = 'moz ms o webkit '.split(' '), // Unprefixed last, see ments.
prefixCount = prefixes.length,
canAnimate = false;
element = doc.appendChild((element)
? element.cloneNode(false)
: document.createElement('div'));
// Detect invalid start value. (Webkit tries to use default.)
element.style[propCamel] = to;
// Iterate through supported prefixes.
for (var i = 0; i < prefixCount; i++) {
// Variations on current prefix.
var prefix = prefixes[i],
hPrefix = (prefix) ? '-' + prefix + '-' : '',
uPrefix = (prefix) ? prefix.toUpperCase() + '_' : '';
// Test for support.
if (CSSRule[uPrefix + 'KEYFRAMES_RULE']) {
// Rule supported; add keyframe rule to test stylesheet.
style.sheet.insertRule('@'+ hPrefix + 'keyframes ' + rule, 0);
// Apply animation.
var animationProp = (hPrefix + 'animation').toCamelCase();
element.style[animationProp] = 'capTest 1s 0s both';
// Get initial puted style.
var before = getComputedStyle(element)[propCamel];
// Skip to last frame of animation.
// BUG: Firefox doesn't support reverse or update node style while
// attached.
doc.removeChild(element);
element.style[animationProp] = 'capTest 1s -1s alternate both';
doc.appendChild(element);
// BUG: Webkit doesn't update style when animation skipped ahead.
element.style[animationProp] = 'capTest 1s 0 reverse both';
// Get final puted style.
var after = getComputedStyle(element)[propCamel];
// If before and after are different, property and values are animable.
canAnimate = before !== after;
break;
}
}
// Clean up the test elements.
doc.removeChild(element);
doc.removeChild(style);
return canAnimate;
}
// Cribbed from Lea Verou's prefixfree.
String.prototype.toCamelCase = function() {
return this.replace(/-([a-z])/g, function($0, $1) { return $1.toUpperCase(); })
.replace('-','');
};
How to use
The mandatory arguments for this are the property to animate and the starting and finishing values it should take. Optionally, you can pass an element with other initial styles set, e.g. position: absolute
. (The function clones the element, so you can pass nodes from the document and they won't be changed.) If you don't pass any element, the animation is tested on a div
with whatever default styles the UA applies.
How it works
A keyframe animation rule is added to a dummy stylesheet, with the initial frame set to the from
value and the final frame set to the to
value. This animation is applied to an element. We then inspect the puted style for the animated property to see if it is different when the animation starts from the initial frame pared to when it starts from the final frame.
The reason this works is because the animable properties for both transitions and keyframe animations are the same, and the browser will only apply keyframe values if the property supports animation.
Caveats (read before using, some of these are nasty!)
There are several inconsistencies in how browsers handle animations. A couple of these I have worked around in as future-proof a way as possible; however, a few of them are intractable.
Most notably, Firefox tweens position values (e.g. left
) on static elements while others (e.g. Webkit and Opera) do not. It doesn't actually move the element, but the value of that property is updated. Thus, you will get different results between browsers if you try to animate a position value without passing a non-statically positioned element.
The most current versions of major browsers that support CSS transitions also support CSS keyframes, although some older versions support the former but not the latter. (E.g. Opera 11.)
Finally, if I were doing this more elegantly I would use prefixfree to determine the correct prefix to use directly; currently I test against an array of prefixes, starting with the unprefixed version.
Edit: see Jordan's answer for a good technique on detecting animatable properties.
I'm afraid there is no straightforward way to detect if a property is animatable. However, the properties are consistent for the most part (the only problem I've encountered is with FF4 transition + text shadow + transform).
http://www.w3/TR/css3-transitions/#the-transition-property-property-#properties-from-css-
Firefox 3.6 doesn't support css transitions, you can detect this with a js library such as Modernizr:
http://www.modernizr./
本文标签: javascriptDetect if property is animatable by CSS3 transitionStack Overflow
版权声明:本文标题:javascript - Detect if property is animatable by CSS3 transition? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741398282a2376506.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论