78 votes

Comment puis-je re-déclencher une WebKit CSS animation via JavaScript?

Donc, j'ai cette -webkit-animation règle:

@-webkit-keyframes shake {
    0% {
        left: 0;
    }
    25% {
        left: 12px;
    }
    50% {
        left: 0;
    }
    75% {
        left: -12px;
    }
    100% {
        left:0;
    }
}

Et un peu de CSS la définition de certains de l'animation des règles sur mon box:

#box{
    -webkit-animation-duration: .02s;
    -webkit-animation-iteration-count: 10;
    -webkit-animation-timing-function: linear;
}

J'ai peut - shake le #box comme ceci:

document.getElementById("box").style.webkitAnimationName = "shake";

Mais je ne peux pas le secouer à nouveau plus tard.

Cela ne secoue la boîte une fois:

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

Comment puis-je re-déclencher les animations CSS via JavaScript sans utiliser de délais d'attente ou de multiples animations?

94voto

David Murdoch Points 28521

J'ai trouvé la réponse basé sur le code source et les exemples à l' CSS3 transition tests github page.

Fondamentalement, les animations CSS ont un animationEnd événement est déclenché lorsque l'animation est terminée.

Pour les navigateurs webkit cet événement est nommé "webkitAnimationEnd". Donc, pour remettre une animation après qu'il a été appelé, vous devez ajouter un écouteur d'événement à l'élément de l' animationEnd événement.

Dans la plaine de la vanille 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.
};

et avec jQuery:

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

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

Le code source de CSS3 tests de transition (mentionné ci-dessus) a support objet qui peut être utile pour les navigateurs les transitions CSS, les transforme et les animations.

Voici le code de prise en charge (re-formaté):

var css3AnimationSupport = (function(){
    var div = document.createElement('div'),
        divStyle = div.style,
        // you'll probably be better off using a `switch` instead of theses ternary ops
        support = {
            transition:
                divStyle.MozTransition     === ''? {name: 'MozTransition'   , end: 'transitionend'} :
                // Will ms add a prefix to the transitionend event?
                (divStyle.MsTransition     === ''? {name: 'MsTransition'    , end: 'msTransitionend'} :
                (divStyle.WebkitTransition === ''? {name: 'WebkitTransition', end: 'webkitTransitionEnd'} :
                (divStyle.OTransition      === ''? {name: 'OTransition'     , end: 'oTransitionEnd'} :
                (divStyle.transition       === ''? {name: 'transition'      , end: 'transitionend'} :
                false)))),
            transform:
                divStyle.MozTransform     === '' ? 'MozTransform'    :
                (divStyle.MsTransform     === '' ? 'MsTransform'     :
                (divStyle.WebkitTransform === '' ? 'WebkitTransform' : 
                (divStyle.OTransform      === '' ? 'OTransform'      :
                (divStyle.transform       === '' ? 'transform'       :
                false))))
            //, animation: ...
        };
    support.transformProp = support.transform.name.replace(/([A-Z])/g, '-$1').toLowerCase();
    return support;
}());

Je n'ai pas ajouté le code pour détecter les "animation" les propriétés de chaque navigateur. J'ai fait cette réponse "wiki de la communauté" et de quitter que pour vous. :-)

14voto

gilly3 Points 33285

Vous devez d'abord supprimer l'animation, puis l'ajouter à nouveau. Par exemple:

document.getElementById("box").style.webkitAnimationName = "";
setTimeout(function ()
{
    document.getElementById("box").style.webkitAnimationName = "shake";
}, 0);

Pour ce faire, sans setTimeout supprimer l'animation lors de onmousedown, et l'ajouter au cours onclick:

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

6voto

Puyol Points 1031

Simple mais efficace, une solution de rechange:

HTML:

<div id="box"></div>
<button id="shake-the-box">Shake it!</button>​

css:

#box{
    background: blue;
    margin:30px;
    height:50px;
    width:50px;
    position:relative;
    -moz-animation:shake .2s 0 linear 1; 
    -webkit-animation:shake .2s 0 linear 1; 
}
#box.trigger{
    display:table;
}
@-webkit-keyframes shake {
    0% {
        left: 0;
    }
    25% {
        left: 12px;
    }
    50% {
        left: 0;
    }
    75% {
        left: -12px;
    }
    100% {
        left:0;
    }
}
@-moz-keyframes shake {
    0% {
        left: 0;
    }
    25% {
        left: 12px;
    }
    50% {
        left: 0;
    }
    75% {
        left: -12px;
    }
    100% {
        left:0;
    }
}​

jQuery:

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

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

});​

Démo:
http://jsfiddle.net/5832R/2/

Questions:
Je ne sais pas si ça marche sur Firefox, parce que l'animation ne semble pas y travailler...

0voto

Nico Prat Points 88

Avec votre code javascript, vous pouvez également ajouter (et puis supprimer) une classe CSS dans laquelle l'animation est déclarée. Voyez ce que je veux dire ?

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X