使用 jQuery 触发 CSS 摇动动画,每隔一段时间都有效……为啥?

Posted

技术标签:

【中文标题】使用 jQuery 触发 CSS 摇动动画,每隔一段时间都有效……为啥?【英文标题】:Using jQuery to trigger CSS shake animation, works every OTHER time ... why?使用 jQuery 触发 CSS 摇动动画,每隔一段时间都有效……为什么? 【发布时间】:2019-06-18 10:49:50 【问题描述】:

我在这里有一个相当简单的小提琴:http://jsfiddle.net/7aotzqmL/2/,它应该在单击链接时用 CSS 动画摇动 div。它有效,但只有每隔一次(每隔一次)。我很难过 - 有人可以帮忙吗?

我看过的其他答案提到了如何在使用 onmouseover 时还需要附加 onmouseout ......但这只是一次点击,所以我不确定这是否相关。我只想让 div 在每次点击时都摇晃一下,而不是其他的。

jsFiddle:https://jsfiddle.net/7aotzqmL/2/

CSS 代码:

$(function() 
  $('a').click(function(ev) 
    $('div').toggleClass('shaker');
    ev.preventDefault();
  );
);
div.shaker 
  animation: shake 0.3s;
  /* When the animation is finished, start again */
  animation-iteration-count: 1; //single shake 


@keyframes shake 
  0% 
    transform: translate(1px, 1px) rotate(0deg);
  
  10% 
    transform: translate(-1px, -2px) rotate(-1deg);
  
  20% 
    transform: translate(-3px, 0px) rotate(1deg);
  
  30% 
    transform: translate(3px, 2px) rotate(0deg);
  
  40% 
    transform: translate(1px, -1px) rotate(1deg);
  
  50% 
    transform: translate(-1px, 2px) rotate(-1deg);
  
  60% 
    transform: translate(-3px, 1px) rotate(0deg);
  
  70% 
    transform: translate(3px, 1px) rotate(-1deg);
  
  80% 
    transform: translate(-1px, -1px) rotate(1deg);
  
  90% 
    transform: translate(1px, 2px) rotate(0deg);
  
  100% 
    transform: translate(1px, -2px) rotate(-1deg);
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a href="#">asd</a>
<div>shake</div>

【问题讨论】:

在我看来,问题在于我的 div 类“shaker”被第二次点击删除了,因为这是对 toggleClass 的第二次调用。这将解释每 2 次工作。但是,当我在调用 toggleClass 之前添加检查时:if ($('div').hasClass('shaker')) $('div').removeClass('shaker'); 它仍然不起作用。有人吗? 【参考方案1】:

试试这个就行了

$(function()
    $('a').click(function(ev)

       $('div').addClass('shaker'); 

       setTimeout(function()

       $('div').removeClass('shaker'); 
       ,300);
        ev.preventDefault();
    );
);

下面的代码是在均匀点击时删除类,而你的动画正在添加类

$('div').toggleClass('shaker');

在上面的解决方案中,div 类会在 0.3 秒动画后被移除,每次点击都会添加 'shaker' 类并且动画会发生

【讨论】:

谢谢,我自己确实想出了相同的解决方案,当我看到问题已经得到回答时,我正要删除这个问题。对于其他有同样问题的人,这个解决方案效果很好!似乎由于其中一些函数是非阻塞的,所以你需要使用 setTimeout,在这种情况下,300 的值对应于动画定义为 0.3s 的事实。如果将 setTimeout() 的参数值设置为小于 300,您将无法看到动画完全完成。 我在my answer 中发布的方法通过在动画完成后删除类来解决该问题。您可以随意更改动画长度,而无需更新超时。我个人尽可能避免使用超时,因为它们非常脆弱并且容易产生难以发现的错误。【参考方案2】:

您正在切换类,因此第一次单击添加它,第二次单击删除它。相反,您可以在单击时添加类并设置一个使用事件侦听器来侦听动画结束,然后删除该类。

$(function() 
  const div = $('.container')
  $('a').click(function(ev) 
    div.addClass('shaker')
    div.one('animationend', () => 
      div.removeClass('shaker')
    )
    ev.preventDefault();
  );

);
.container 
  opacity: 1;
  width: 100px;
  height: 100px;
  background: red;


.container.shaker 
  /* Start the shake animation and make the animation last for 0.5 seconds */
  animation: shake 0.3s;
  /* When the animation is finished, start again */
  animation-iteration-count: 1; //single shake 


@keyframes shake 
  0% 
    transform: translate(1px, 1px) rotate(0deg);
  
  10% 
    transform: translate(-1px, -2px) rotate(-1deg);
  
  20% 
    transform: translate(-3px, 0px) rotate(1deg);
  
  30% 
    transform: translate(3px, 2px) rotate(0deg);
  
  40% 
    transform: translate(1px, -1px) rotate(1deg);
  
  50% 
    transform: translate(-1px, 2px) rotate(-1deg);
  
  60% 
    transform: translate(-3px, 1px) rotate(0deg);
  
  70% 
    transform: translate(3px, 1px) rotate(-1deg);
  
  80% 
    transform: translate(-1px, -1px) rotate(1deg);
  
  90% 
    transform: translate(1px, 2px) rotate(0deg);
  
  100% 
    transform: translate(1px, -2px) rotate(-1deg);
  
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<a href="#">asd</a>
<div class="container"></div>

【讨论】:

【参考方案3】:

嗯,首先,您正在切换课程。所以单击意味着“添加”,下一个意味着“删除”。此外,“preventdefault”应首先出现,以防止在尝试添加或删除类之前锚标记的默认行为。


    $(function()
          $('a').click(function(ev)
              ev.preventDefault();
              $('div').addClass('shaker'); 
              setTimeout(()=> 
                  $('div').removeClass('shaker');
              ,300)
          );
      );

【讨论】:

【参考方案4】:
$(function()
$('a').click(function(ev)
  $('div').addClass('shaker'); 
   setTimeout(()=>
   $('div').removeClass('shaker');
   ,300)
    ev.preventDefault();
);
);

使用上面的代码。您正在删除 shaker 类。

【讨论】:

以上是关于使用 jQuery 触发 CSS 摇动动画,每隔一段时间都有效……为啥?的主要内容,如果未能解决你的问题,请参考以下文章

UILocalNotification 声音每隔一段时间播放一次

android 动画, 请问这个动画怎么解决啊?哪位有思路啊?谢谢!

在 JavaScript 中触发 CSS 动画

什么更快? CSS3 过渡还是 jQuery 动画?

CSS3 旋转动画导致 Animate.css 抖动动画消失

利用jQuery Ajax技术实现每隔5秒向某页面传值