CSS3动画填充模式polyfill

时间:2012-09-21 16:14:46

标签: jquery animation css3 modernizr polyfills

前言

让我们假装divopacity:0;动画到opacity:1;,我想在动画结束后保留​​opacity:1;

这就是animation-fill-mode:forwards;的作用。

@keyframes myAnimation {
    from { opacity:0; }
    to { opacity:1; }
}
div {
    opacity:0;
    animation-name:myAnimation;
    animation-delay:1s;
    animation-duration:2s;
    animation-fill-mode:forwards;
}​
<div>just a test</div>​

Run it on jsFiddle

  • 注1:我在此处未包含供应商前缀以简化
  • 注2:这只是一个例子,请不要回复“只使用jQuery fadeIn函数”等。

要了解的一些事情

this answer中,我读到Chrome 16 +,Safari 4 +,Firefox 5 +支持animation-fill-mode

animation单独is supported by Chrome 1+和Opera也是如此。因此,即使fill-mode不受支持,Modernizr的常规测试也可能会返回正值。

要定位animation-fill-mode,我在Modernizr上添加了一个新测试:

Modernizr.addTest('animation-fill-mode',function(){
    return Modernizr.testAllProps('animationFillMode');
});

现在我有一个用于CSS的.no-animation-fill-mode类和用于JavaScript的Modernizr.animationFillMode

我还从CSS3 animations specs读到:

  

文档样式表中指定的动画将从   文件加载


最后,问题

可以在确切的秒数动画结束时运行一个简单的jQuery函数

$(document).ready(function(){
    if(!Modernizr.animation){
        $('div').delay(1000).fadeIn(2000);
    }else if(!Modernizr.animationFillMode){
        $('div').delay(3000).show();
    }
});

在CSS中:

.no-animation-fill-mode div {
    animation-iteration-count:1;
}
/* or just animation:myAnimation 2s 1s 1; for everyone */

animation-fill-mode是否有任何已知的特定


此外,如果我使用简写语法

会发生什么
animation:myAnimation 2s 1s forwards;

支持animation但不支持animation-fill-mode的浏览器?

非常感谢!

3 个答案:

答案 0 :(得分:6)

如果是我,我会尝试选择更简单的替代方案 - 如果可能的话。我会降级我的实现,以便我只使用通常接受的内容。稍后,当该功能得到更广泛的支持时,我会考虑实现它。我很少考虑使用在文档页面上播放This is an experimental technology的功能 - 但是我可能会被归类为无聊:)

在您的示例中,您可以通过最初定义元素的结束状态,并使用链接动画(如果需要执行操作之前的延迟)来获得与animation-fill-mode:forwards相同的结果

@keyframes waitandhide {
  from { opacity:0; }
  to { opacity:0; }
}
@keyframes show {
  from { opacity:0; }
  to { opacity:1; }
}
div {
  opacity:1;
  animation: waitandhide 2s 0s, show 2s 2s;
}
<div>just a test</div>​

http://jsfiddle.net/RMJ8s/1/

现在,较慢的浏览器可能会闪烁您的初始元素状态,然后再将它们隐藏起来。但根据我的经验,我只在非常旧的机器上以及有大量css要渲染的页面上看到过这种情况。

显然上面的内容会使你的css更加膨胀(因为你必须复制样式),并且在处理复杂的动画时会更复杂。但是:

  1. 它应该适用于任何动画情况。
  2. 这将避免使用JavaScript (除了$(。。fadeIn后备)
  3. 它适用于所有支持CSS动画的浏览器。
  4. 您不会冒JS和CSS变得不同步的风险。
  5. 关于使用短格式,最好不要为了达到尽可能广泛的浏览器兼容性。但是,如上面的示例所示,我选择使用短格式,因为它们更清晰,我可以理解不想一直编写(或读取)冗长的版本。出于这个原因,我建议使用less来生成你的css:

    http://lesscss.org/

    http://radiatingstar.com/css-keyframes-animations-with-less

答案 1 :(得分:2)

我不知道任何polyfill ... 但我要说你应该使用你自己的自定义Modernizr测试,对于不支持动画填充模式的浏览器,你应该使用animationEnd事件来触发你的回调并将不透明度设置为1(或删除一个类)。

请参阅:CSS3 transition events

至于速记符号,IE&lt; 10不支持动画填充模式属性,我很确定它会破坏整个声明。

答案 2 :(得分:0)

仅供参考,这就是我现在如何实施pebbl的答案(这是一个非常聪明的答案)。我只需要Modernizr的css-animation检测。

让我们假设我想滑动并淡化这个div:

<div class="target">Some stuff</div>

首先,我用供应商前缀

写下动画
@keyframes byebye {
    0% { height:100px; opacity:1; }
    100% { opacity:0; height:0; }
}

然后是一个新类

.target-animation {
    height:0; opacity:0; // same as "100%" state
    animation:byebye 750ms 1;
}

转到javascript:

// $('.whatever').on('click',function(){ ...

if(Modernizr.cssanimations)
    // css animations are supported!
    $('.target').addClass('target-animation');
else
    // i hate you IE
    $('.target').animate({height:0,opacity:0},750);

Demo

如果您需要多次触发动画,只需按照here解释的javascript删除该类:

// if(Modernizr.cssanimations) ...

$('target').addClass('target-animation').on('webkitAnimationEnd oAnimationEnd oanimationend animationend msAnimationEnd',function(){
    $(this).removeClass('target-animation')
    // don't forget to  .hide()  if needed
});

// ... else