在CSS3中重启动画:除了删除元素之外还有什么更好的方法?

Leo*_*Leo 46 javascript css3

我有一个需要在点击时重新启动的CSS3动画.这是一个显示剩余时间的酒吧.我正在使用scaleY(0)变换来创建效果.

现在我需要通过将条形图恢复到scaleY(1)来重新启动动画,然后再次转到scaleY(0).我第一次尝试设置scaleY(1)失败,因为它需要相同的15秒才能恢复到全长.即使我将持续时间更改为0.1秒,我也需要延迟或链接scaleY(0)的分配以使条形补充完成.对于这么简单的任务来说,感觉太复杂了.

我还发现了一个有趣的提示,通过从文档中删除元素重新启动动画,然后重新插入它的克隆:http: //css-tricks.com/restart-css-animation/

它有效,但有没有更好的方法来重新启动CSS动画?我正在使用Prototype和Move.js,但我并不局限于它们.

Lea*_*rou 62

只需animation通过JavaScript 设置属性"none",然后设置更改属性的超时"",以便它再次从CSS继承.

这里是Webkit的演示:http://jsfiddle.net/leaverou/xK6sa/ 但是,请记住,在实际使用中,你还应该包括-moz-(至少).

  • 现在是2019年,[供应商前缀](/sf/ask/569229251/)不再需要。 (2认同)
  • 为了避免 @Eric 描述的超时问题,您可以调用“void element.offsetWidth;”来强制在动画属性更改之间进行回流,而不是使用超时。 (2认同)

use*_*ser 38

不需要超时,使用reflow来应用更改:

function reset_animation() {
  var el = document.getElementById('animated');
  el.style.animation = 'none';
  el.offsetHeight; /* trigger reflow */
  el.style.animation = null; 
}
Run Code Online (Sandbox Code Playgroud)
#animated {
  position: absolute;
  width: 50px; height: 50px;
  background-color: black;
  animation: bounce 3s ease-in-out infinite;
}
@keyframes bounce {
  0% { left: 0; }
  50% { left: calc( 100% - 50px ); }
  100% { left: 0; }
}
Run Code Online (Sandbox Code Playgroud)
<div id="animated"></div>
<button onclick="reset_animation()">Reset</button>
Run Code Online (Sandbox Code Playgroud)

  • 您还可以通过调用[properties/method](https://gist.github.com/paulirish/5d52fb081b3570c81e3a)中的任何一个来触发重排,而不仅仅是`offsetHeight`. (4认同)
  • 对于 Typescript 用户,您需要使用 `el.style.animation = '';` 而不是上面的,因为 `animation` 需要一个字符串。 (4认同)
  • @D_S_X 其工作方式是使用优先的样式属性覆盖 CSS。然后,您回流并删除此覆盖,并且您的元素再次执行其动画。 (4认同)
  • 触发回流不会影响性能吗?从性能角度来看,这与所选答案相比如何? (3认同)
  • reflow 比选择的 anwser 好 (2认同)

V. *_*tti 22

@ZachB关于 Web 动画 API 的回答似乎是“正确的”\xe2\x84\xa2 方法,但不幸的是似乎要求您通过 JavaScript 定义动画。然而它引起了我的注意,我发现了一些有用的相关内容:

\n

Element.getAnimations()Document.getAnimations()

\n

截至 2021 年,对他们的支持相当好。

\n

就我而言,我想同时重新启动页面上的所有动画,所以我所要做的就是:

\n
const replayAnimations = () => {\n  document.getAnimations().forEach((anim) => {\n    anim.cancel();\n    anim.play();\n  });\n};\n
Run Code Online (Sandbox Code Playgroud)\n

但在大多数情况下,人们可能会想要选择重新启动哪个动画......

\n

getAnimations返回一堆CSSAnimationCSSTransition对象,如下所示:

\n
animationName: "fade"\ncurrentTime: 1500\neffect: KeyframeEffect\n  composite: "replace"\n  pseudoElement: null\n  target: path.line.yellow\nfinished: Promise {<fulfilled>: CSSAnimation}\nplayState: "finished"\nready: Promise {<fulfilled>: CSSAnimation}\nreplaceState: "active"\ntimeline: DocumentTimeline {currentTime: 135640.502}\n\n# ...etc\n
Run Code Online (Sandbox Code Playgroud)\n

因此,您可以使用animationNametarget属性来选择您想要的动画(尽管有点迂回)。

\n
\n

编辑

\n

这是一个方便的函数,仅使用 可能会更兼容Document.getAnimations,并添加 TypeScript 进行演示:

\n
// restart animations on a given dom element\nexport const restartAnimations = (element: Element): void => {\n  for (const animation of document.getAnimations()) {\n    if (\n      animation.effect instanceof KeyframeEffect &&\n      element.contains(animation.effect.target)\n    ) {\n      animation.cancel();\n      animation.play();\n    }\n  }\n};\n
Run Code Online (Sandbox Code Playgroud)\n


big*_*osh 8

  1. 将动画实现为 CSS 描述符
  2. 将描述符添加到元素以开始动画
  3. 使用animationend事件处理函数在动画完成时移除描述符,以便下次您想要重新启动动画时再次添加它。

---HTML---

<div id="animatedText">
Animation happens here
</div>

<script>

  function startanimation(element) {

    element.classList.add("animateDescriptor");

    element.addEventListener( "animationend",  function() {

      element.classList.remove("animateDescriptor");    

    } );

  }

</script>


<button onclick="startanimation( document.getElementById('animatedText') )">
Click to animate above text
</button>
Run Code Online (Sandbox Code Playgroud)

---CSS---

@keyframes fadeinout {  
      from { color: #000000; }  
    25% {color: #0000FF; }  
    50% {color: #00FF00; }      
    75% {color: #FF0000; }  
      to { color : #000000; }   
  } 

  .animateDescriptor {  
    animation: fadeinout 1.0s;  
  }     
Run Code Online (Sandbox Code Playgroud)

在这里试试:

https://jsfiddle.net/bigjosh/avp9Lk6r/50/

  • 使用animationend 事件是一个好主意,尽管您并不真的希望每次动画运行时都添加新的事件侦听器。只需将其添加到 div 一次即可。 (2认同)

Usa*_*jid 8

也可以使用display属性,只需将display设置为none即可。

display:none;
Run Code Online (Sandbox Code Playgroud)

并且更改将其支持为阻止(或您想要的任何其他属性)。

display:block;
Run Code Online (Sandbox Code Playgroud)

使用 JavaScript。

它会产生惊人的效果。


小智 6

如果你有一些类CSS3动画,为exapmle .blink那么你可以removeClass一些元素和addClass这个元素想到的setTimeout与1个milisecond通过点击.

  $("#element").click(function(){
     $(this).removeClass("blink");

     setTimeout(function(){
       $(this).addClass("blink);
    },1 ///it may be only 1 milisecond, it's enough
  });
Run Code Online (Sandbox Code Playgroud)