Donc, j'ai ceci -webkit-animation
règle:
@-webkit-keyframes shake {
0% {
left: 0;
}
25% {
left: 12px;
}
50% {
left: 0;
}
75% {
left: -12px;
}
100% {
left:0;
}
}
Et quelques CSS définissant certaines des règles d’animation sur mon box
:
#box{
-webkit-animation-duration: .02s;
-webkit-animation-iteration-count: 10;
-webkit-animation-timing-function: linear;
}
Je peux shake
le #box
comme ça:
document.getElementById("box").style.webkitAnimationName = "shake";
Mais je ne peux plus le secouer plus tard.
Cela secoue la boîte une seule fois:
someElem.onclick = function(){
document.getElementById("box").style.webkitAnimationName = "shake";
}
Comment puis-je réactiver une animation CSS via JavaScript sans utiliser de délais d'expiration ou de multiples animations?
J'ai trouvé la réponse basée sur le code source et des exemples à la page page des tests de transition CSS3 github .
Fondamentalement, les animations CSS ont un événement animationEnd
qui est déclenché à la fin de l'animation.
Pour les navigateurs Webkit, cet événement est nommé "webkitAnimationEnd
". Ainsi, pour réinitialiser une animation après son appel, vous devez ajouter un écouteur d'événement à l'élément pour l'événement animationEnd
.
En plain vanilla 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 tests de transition CSS (mentionné ci-dessus) contient l'objet support
qui peut être utile pour les transitions CSS, les transformations et les animations entre navigateurs.
Voici le code de support (reformaté):
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 propriétés "d'animation" de chaque navigateur. J'ai fait cette réponse "wiki de la communauté" et je vous le laisse. :-)
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, supprimez l'animation pendant onmousedown
et ajoutez-la pendant onclick
:
someElem.onmousedown = function()
{
document.getElementById("box").style.webkitAnimationName = "";
}
someElem.onclick = function()
{
document.getElementById("box").style.webkitAnimationName = "shake";
}
Une alternative simple mais efficace:
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/
Problèmes:
Je ne sais pas si cela fonctionne sur Firefox, car l'animation ne semble pas fonctionner là-bas ...
Suite à la suggestion de https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Animations/Tips , supprimez puis ajoutez la classe d'animation, à l'aide de requestAnimationFrame pour vous assurer que le rendu Le moteur traite les deux modifications. Je pense que cela est plus propre que d'utiliser setTimeout et gère la lecture d'une animation avant la fin de la lecture précédente.
$('#shake-the-box').click(function(){
$('#box').removeClass("trigger");
window.requestAnimationFrame(function(time) {
window.requestAnimationFrame(function(time) {
$('#box').addClass("trigger");
});
});
});
Le clone fonctionne plutôt bien sur une pause Karaoké: sur IE11, il fallait forcer un refoulement (version plus courte de R. Krupiński).
$('#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));
}
ou vous pouvez utiliser les éléments suivants:
function resetAnimation(Elm) {
$('#'+Elm).replaceWith($('#'+Elm).clone(true));
}
Existe-t-il un problème d'utilisation de setTimeout()
pour supprimer la classe, puis la lire 5 ms plus tard?
svg.classList.remove('animate');
setTimeout(function() {
svg.classList.add('animate');
}, 10);
Réinitialiser la valeur en premier. Utilisez le refusion pour appliquer la modification sans utiliser le délai d'expiration:
function shake() {
var box = document.getElementById("box");
box.style.animationName = null;
box.offsetHeight; /* trigger reflow */
box.style.animationName = "shake";
}
@keyframes shake {
0% { left: 0; }
25% { left: 12px; }
50% { left: 0; }
75% { left: -12px; }
100% { left: 0; }
}
#box {
position: absolute;
width: 75px; height: 75px;
background-color: black;
animation-duration: .02s;
animation-iteration-count: 10;
animation-timing-function: linear;
}
button {
position: absolute;
top: 100px;
}
<div id="box"></div>
<button onclick="shake()">Shake</button>
Contrairement à la réponse acceptée qui recommande animationEnd
, cette méthode réinitialise l'animation même si elle est encore en cours. Cela pourrait être ou ne pas être ce que vous voulez.
Une alternative serait de créer un duplicata @keyframes
_ animation et bascule entre les deux:
function shake() {
var box = document.getElementById("box");
if (box.style.animationName === "shake")
box.style.animationName = "shake2";
else
box.style.animationName = "shake";
}
@keyframes shake {
0% { left: 0; }
25% { left: 12px; }
50% { left: 0; }
75% { left: -12px; }
100% { left: 0; }
}
@keyframes shake2 {
0% { left: 0; }
25% { left: 12px; }
50% { left: 0; }
75% { left: -12px; }
100% { left: 0; }
}
#box {
position: absolute;
width: 75px; height: 75px;
background-color: black;
animation-duration: .02s;
animation-iteration-count: 10;
animation-timing-function: linear;
}
button {
position: absolute;
top: 100px;
}
<div id="box"></div>
<button onclick="shake()">Shake</button>
Avec votre javascript, vous pouvez également ajouter (puis supprimer) une classe CSS dans laquelle l’animation est déclarée. Tu vois ce que je veux dire ?
#cart p.anim {
animation: demo 1s 1; // Fire once the "demo" animation which last 1s
}
1) Ajoutez le nom de l'animation au #box.trigger
en 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) En Java-script, vous ne pouvez pas supprimer la classe trigger
.
3) Supprimez le nom de la classe en utilisant la méthode setTimeOut
.
$(document).ready(function(){
$('#shake-the-box').click(function(){
$('#box').addClass('trigger');
setTimeout(function(){
$("#box").removeClass("trigger")},500)
});
});
4) Voici le DÉMO .