可以使用CSS3过渡设置动画效果的属性列表在不同的浏览器中并不一致,并且可能会随着新的浏览器版本而发生变化。例如,-moz变换在FF3.6中不能使用-moz变换设置动画,但它在FF4中。
那么,有没有一种方法可以在JavaScript中检测特定属性是否可设置动画?我不喜欢使用用户代理嗅探,因为它不可靠。
提前感谢!
发布于 2011-01-13 13:00:20
编辑:有关检测动画属性的好技术,请参阅 。
恐怕没有直接的方法来检测属性是否可设置动画。然而,属性在很大程度上是一致的(我遇到的唯一问题是FF4转换+文本阴影+转换)。
http://www.w3.org/TR/css3-transitions/#the-transition-property-property-#properties-from-css-
Firefox 3.6不支持css转换,你可以用一个js库检测到这一点,比如:
发布于 2012-06-26 22:49:07
是的,有一种方法。演示如下,解释如下。涉及到一些非常重要的警告,所以一定要继续往下读。
下面的代码将测试浏览器是否可以在两个值之间设置动画。
代码
/*
@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 comments.
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 computed 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 computed 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('-','');
};
如何使用
它的强制参数是要动画的属性以及它应该采用的起始值和结束值。可选的,你可以传递一个设置了其他初始样式的元素,例如position: absolute
。(该函数克隆元素,因此您可以传递文档中的节点,并且这些节点不会被更改。)如果您没有传递任何元素,动画将在UA应用的任何默认样式的div
上进行测试。
它是如何工作的
关键帧动画规则将添加到虚拟样式表中,其中初始帧设置为from
值,最后一帧设置为to
值。此动画应用于元素。然后,我们检查动画属性的计算样式,以查看动画从初始帧开始时与从最终帧开始时是否不同。
这样做的原因是,变换和关键帧动画的可动画属性是相同的,并且如果该属性支持动画,浏览器将仅应用关键帧值。
注意事项(在使用之前,请阅读其中一些令人讨厌的内容!)
浏览器处理动画的方式有几个不一致之处。其中几个我已经解决了,作为一种可能的面向未来的方法;然而,其中一些是难以处理的。
最值得注意的是,火狐补间静态元素的位置值(例如left
),而其他的(例如Webkit和Opera)则不是。它实际上不会移动元素,但会更新该属性的值。因此,如果您尝试在不传递非静态定位元素的情况下对位置值进行动画处理,您将在不同的浏览器中获得不同的结果。
支持CSS过渡的主要浏览器的最新版本也支持CSS关键帧,尽管一些较旧的版本支持前者,但不支持后者。(例如,Opera 11。)
最后,如果我要更优雅地做这件事,我将使用prefixfree来确定要直接使用的正确前缀;目前,我对前缀数组进行测试,从无前缀版本开始。
https://stackoverflow.com/questions/4679288
复制