在 CSS3 中重新启动动画:还有比移除元素更好的方法吗?

IT技术 javascript css
2021-01-20 08:17:09

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

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

我还发现了一个有趣的技巧,可以通过从文档中删除元素来重新启动动画,然后重新插入它的一个副本:http : //css-tricks.com/restart-css-animation/

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

6个回答

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

function reset_animation() {
  var el = document.getElementById('animated');
  el.style.animation = 'none';
  el.offsetHeight; /* trigger reflow */
  el.style.animation = null; 
}
#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; }
}
<div id="animated"></div>
<button onclick="reset_animation()">Reset</button>

触发回流不会影响性能吗?这与所选答案相比如何,性能方面?
2021-03-20 08:17:09
@card100,你能举个例子吗?
2021-04-02 08:17:09
这不适用于应用了 1 个以上动画的元素。
2021-04-04 08:17:09
您还可以通过调用这些属性/方法中的任何一个来触发回流,而不仅仅是offsetHeight.
2021-04-06 08:17:09
el.style.animation = null; 这段代码中的行是做什么的?
2021-04-08 08:17:09

只需animation通过 JavaScript属性设置"none",然后设置一个超时,将属性更改为"",因此它再次从 CSS 继承。

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

为避免@Eric 描述的超时问题,您可以调用void element.offsetWidth;以在动画属性更改之间强制重排,而不是使用超时。
2021-03-12 08:17:09
现在是 2019 年,不再需要供应商前缀
2021-03-19 08:17:09
谢谢莉亚。差不多了 :),如果我将您的动画更改为仅运行一次,我将无法获得相同的效果。当我点击时,动画不会重新开始。
2021-03-30 08:17:09
不够好,因为有时超时时间太长会出现缺陷,而超时时间太短则没有效果。如果您需要在动画仍在播放时重新启动动画,则不建议使用。
2021-03-30 08:17:09
非常感谢!- 但不幸的是我无法让它在 Safari 中工作。Chrome、Edge 和 Firefox 按预期工作。我使用以下代码:var anim = jQuery(mutation.target).find(".background.background-image:first").get(0); anim.style.WebkitAnimation = 'none'; anim.style.animation = 'none'; setTimeout(function() { anim.style.WebkitAnimation = ''; anim.style.animation = ''; }, 10); }
2021-04-07 08:17:09

如果你有一些类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
  });
@FabienSnauwaert 感谢您的评论,您可能是对的,因为我在 ~FF 50 上进行了测试
2021-03-31 08:17:09
好像不太靠谱 使用 1 毫秒计时器对我不起作用,开始使用更高的值(在 Firefox 67 中)。
2021-04-04 08:17:09
  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>

---CSS---

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

  .animateDescriptor {  
    animation: fadeinout 1.0s;  
  }     

在这里试试:

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

使用 animationend 事件是一个好主意,尽管您真的不想在动画运行时添加新的事件侦听器。只需将它添加到 div 一次。
2021-03-22 08:17:09

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

display:none;

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

display:block;

使用 JavaScript。

它会产生惊人的效果。