如何通过JavaScript重新触发WebKit CSS动画?

如何通过JavaScript重新触发WebKit CSS动画?,javascript,css,html,animation,webkit,Javascript,Css,Html,Animation,Webkit,所以,我有一个-webkit动画规则: @-webkit-keyframes shake { 0% { left: 0; } 25% { left: 12px; } 50% { left: 0; } 75% { left: -12px; } 100% { left:0; } } 还有一些CSS在我的框中定义了一些动画规则: #box{

所以,我有一个
-webkit动画
规则:

@-webkit-keyframes shake {
    0% {
        left: 0;
    }
    25% {
        left: 12px;
    }
    50% {
        left: 0;
    }
    75% {
        left: -12px;
    }
    100% {
        left:0;
    }
}
还有一些CSS在我的
框中定义了一些动画规则:

#box{
    -webkit-animation-duration: .02s;
    -webkit-animation-iteration-count: 10;
    -webkit-animation-timing-function: linear;
}
我可以像这样摇动
盒子

document.getElementById("box").style.webkitAnimationName = "shake";
但我以后再也摇不动了

这只会震动盒子一次:

someElem.onclick = function(){
    document.getElementById("box").style.webkitAnimationName = "shake";
}
如何在不使用超时或多个动画的情况下通过JavaScript重新触发CSS动画?

您必须先删除动画,然后再添加动画。例如:

document.getElementById("box").style.webkitAnimationName = "";
setTimeout(function ()
{
    document.getElementById("box").style.webkitAnimationName = "shake";
}, 0);
要在不设置超时的情况下执行此操作,请在
onmousedown
期间删除动画,并在
onclick
期间添加动画:

someElem.onmousedown = function()
{
    document.getElementById("box").style.webkitAnimationName = "";
}
someElem.onclick = function()
{
    document.getElementById("box").style.webkitAnimationName = "shake";
}

我根据源代码和示例找到了答案

基本上,CSS动画有一个
animationEnd
事件,该事件在动画完成时触发

对于webkit浏览器,此事件名为“
webkitAnimationEnd
”。因此,为了在调用动画后重置动画,需要为
animationEnd
事件的元素添加一个事件侦听器

在普通javascript中:

var element = document.getElementById('box');

element.addEventListener('webkitAnimationEnd', function(){
    this.style.webkitAnimationName = '';
}, false);

document.getElementById('button').onclick = function(){
    element.style.webkitAnimationName = 'shake';
    // you'll probably want to preventDefault here.
};
对于jQuery:

var $element = $('#box').bind('webkitAnimationEnd', function(){
    this.style.webkitAnimationName = '';
});

$('#button').click(function(){
    $element.css('webkitAnimationName', 'shake');
    // you'll probably want to preventDefault here.
});

(上述)的源代码具有以下
支持
对象,这可能有助于跨浏览器CSS转换、变换和动画

以下是支持代码(重新格式化):


我没有添加代码来检测每个浏览器的“动画”属性。我在“社区维基”中给出了这个答案,并将其留给您。:-)

使用javascript,还可以添加(然后删除)一个声明动画的CSS类。明白我的意思吗

#cart p.anim {
  animation: demo 1s 1; // Fire once the "demo" animation which last 1s
}

一个简单但有效的替代方案:

HTML:

jQuery:

$('#shake-the-box').click(function(){

  $('#box').toggleClass('trigger');

});​
演示:

问题:
我不知道它是否能在Firefox上运行,因为动画在Firefox上似乎不起作用…

1)将动画名称添加到css中的
#框中

#box.trigger{
    display:table;
    animation:shake .2s 0 linear 1;
    -moz-animation:shake .2s 0 linear 1; 
    -webkit-animation:shake .2s 0 linear 1;
}
2) 在java脚本中,不能删除类
触发器

3) 使用
setTimeOut
方法删除类名

$(document).ready(function(){
    $('#shake-the-box').click(function(){

    $('#box').addClass('trigger');
    setTimeout(function(){
        $("#box").removeClass("trigger")},500)        
    });
}); 

4) 以下是。

克隆对暂停的卡拉OK非常有效: IE11必须强制回流(R.Krupiński的较短版本)

或者,您可以使用以下选项:

function resetAnimation(elm) {
  $('#'+elm).replaceWith($('#'+elm).clone(true)); 
}

按照中的建议,删除然后添加动画类,使用requestAnimationFrame确保渲染引擎处理这两个更改。我认为这比使用setTimeout更干净,可以在上一个播放完成之前处理动画的重放

$('#shake-the-box').click(function(){   
  $('#box').removeClass("trigger");
  window.requestAnimationFrame(function(time) {
  window.requestAnimationFrame(function(time) {
      $('#box').addClass("trigger");
    });
    });    
}))


首先重置该值。使用回流应用更改而不使用超时:

函数抖动(){
var-box=document.getElementById(“box”);
box.style.animationName=null;
box.offsetHeight;/*触发回流焊*/
box.style.animationName=“抖动”;
}
@关键帧抖动{
0%{左:0;}
25%{左:12px;}
50%{左:0;}
75%{左:-12px;}
100%{左:0;}
}
#盒子{
位置:绝对位置;
宽度:75px;高度:75px;
背景色:黑色;
动画持续时间:.02s;
动画迭代次数:10次;
动画计时功能:线性;
}
钮扣{
位置:绝对位置;
顶部:100px;
}


Shake
使用
setTimeout()
删除该类,然后在5毫秒后读取该类是否存在问题

svg.classList.remove('animate');
setTimeout(function() {
  svg.classList.add('animate');
}, 10);

jQuery或类似的库是一种选择吗?您可能会看到更好的浏览器支持。jQuery是可用的,但在我的情况下并不真正适用。我不需要其他浏览器支持,因为它将仅在AdobeAIR中运行。我试图坚持使用css动画而不是javascript。相关:对于所有浏览器:请看,这与我提出的相同。但是如果可能的话,我想不使用setTimeout。我已经用一个不使用setTimeout的替代方法更新了我的答案。这很有效,但出于某种原因,溢出规则被忽略..我将其设置为隐藏,但在动画溢出显示之后,引用的源代码已被移动到注意:github repo中的代码自回答后已更改;那里的代码和这里的代码现在完全不同了。请注意,如果有一个CSS规则将动画分配给对象,将其设置为
'
将使其继承CSS规则,在这种情况下,有必要将其设置为
。注意:根据,最好使用例如
无效(box.offsetHeight)相反,因为具有var访问且没有效果的语句可能会被优化掉(并将触发linter发出警告,如语句位置的
意外表达式“.”。
-由JSLint提供),所以请注意,回流操作是相当“繁重”(计算密集型)的操作。
$('#lyrics').text("Why does it hurt when I pee?");
changeLyrics('3s');  

function changeLyrics(sec) {
  str = 'lyrics '+ sec + ' linear 1';
  $('#lyrics').css( 'animation', str);
  $('#lyrics').css( 'animation-play-state', 'running' );
  $('#lyrics').replaceWith($('#lyrics').clone(true)); 
}
function resetAnimation(elm) {
  $('#'+elm).replaceWith($('#'+elm).clone(true)); 
}
$('#shake-the-box').click(function(){   
  $('#box').removeClass("trigger");
  window.requestAnimationFrame(function(time) {
  window.requestAnimationFrame(function(time) {
      $('#box').addClass("trigger");
    });
    });    
svg.classList.remove('animate');
setTimeout(function() {
  svg.classList.add('animate');
}, 10);