在编写 催眠螺旋 演示时,出现了一个问题,即我希望在可能的情况下使用 CSS 动画,但有一个回退方案来旋转元素。由于我不想依赖 CSS 动画,因此我认为手动编写它毫无意义,而是在浏览器支持的情况下使用 JavaScript 创建它。以下是如何实现的。
测试动画的支持意味着测试是否支持 style 属性。
var animation = false,
animationstring = 'animation',
keyframeprefix = '',
domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),
pfx = '';
if( elm.style.animationName ) { animation = true; }
if( animation === false ) {
for( var i = 0; i < domPrefixes.length; i++ ) {
if( elm.style[ domPrefixes[i] + 'AnimationName' ] !== undefined ) {
pfx = domPrefixes[ i ];
animationstring = pfx + 'Animation';
keyframeprefix = '-' + pfx.toLowerCase() + '-';
animation = true;
break;
}
}
}
[更新 - 之前的代码没有检查浏览器是否支持无前缀的动画 - 这个版本检查了]
这会检查浏览器是否支持任何前缀的动画。如果支持,动画字符串将是 'animation',并且不需要任何关键帧前缀。如果不支持,则遍历所有浏览器前缀(截至目前:))并检查 style 集合上是否存在名为浏览器前缀 + AnimationName
的属性。如果存在,则循环退出,并定义正确的动画字符串和关键帧前缀,并将 animation 设置为 true。在 Firefox 中,这将导致 MozAnimation
和 -moz-
,在 Chrome 中导致 WebkitAnimation
和 -webkit-
等等。然后,我们可以使用它在 JavaScript 中创建一个新的 CSS 动画。如果所有前缀检查都没有返回支持的 style 属性,则以替代方式进行动画处理。
if( animation === false ) {
// animate in JavaScript fallback
} else {
elm.style[ animationstring ] = 'rotate 1s linear infinite';
var keyframes = '@' + keyframeprefix + 'keyframes rotate { '+
'from {' + keyframeprefix + 'transform:rotate( 0deg ) }'+
'to {' + keyframeprefix + 'transform:rotate( 360deg ) }'+
'}';
if( document.styleSheets && document.styleSheets.length ) {
document.styleSheets[0].insertRule( keyframes, 0 );
} else {
var s = document.createElement( 'style' );
s.innerHTML = keyframes;
document.getElementsByTagName( 'head' )[ 0 ].appendChild( s );
}
}
定义了动画字符串后,我们可以在元素上设置(快捷方式)动画。现在,添加关键帧比较棘手。由于它们不是原始动画的一部分,而是与 CSS 语法中分离的(为了提供更大的灵活性和允许重复使用),因此我们无法在 JavaScript 中设置它们。相反,我们需要将它们写成 CSS 字符串。
如果文档中已应用了样式表,则将此关键帧定义字符串添加到该样式表中,如果没有可用的样式表,则使用我们的关键帧创建一个新的样式块并将其添加到文档中。
您可以在 JSFiddle 上查看检测的实际效果和回退 JavaScript 解决方案。
非常简单,但也比我最初想象的要复杂一些。您还可以动态检测和更改当前动画,如 Wayne Pan 的这篇文章 和 Joe Lambert 的这个演示 所解释的那样,但这似乎也相当冗长。
例如,我希望有一个 CSSAnimations
集合,您可以在其中以 JSON 或字符串的形式存储不同的动画,并将其名称作为键。目前,动态创建新规则并将其添加到文档中或附加到规则集中似乎是唯一跨浏览器的途径。有什么想法吗?
关于 Chris Heilmann
HTML5 和开放网络的布道者。让我们修复它!
5 条评论