2015-02-18 17 views
6

Próbuję odtworzyć określoną animację za każdym naciśnięciem przycisku.Animacja jQuery + Animate.css działa tylko raz, animacja nie resetuje się

W szczególności używam biblioteki jQuery i animate.css dla tego efektu: po kliknięciu przycisku dodaje się klasę (dwie klasy, aby dokładnie: fadeInDown animated) do elementu, który chcę animować.

Animacja działa poprawnie, ale tylko jeden raz. Dlaczego to?

Fiddle: http://jsfiddle.net/jqm4vjLj/2/

Chcę animacja zresetować przy każdym kliknięciu przycisku, nawet jeśli jest w połowie realizacji z poprzedniego kliknięcia. Powinien również działać, gdy kliknę przycisk, nie tylko jeden raz.

JS:

$("#button").click(function() { 
    $("#button").removeClass(); 
    $("#button").addClass("fadeInDown animated"); 
}); 

klas z animate.css:

@-webkit-keyframes fadeInDown { 
    0% { 
    opacity: 0; 
    -webkit-transform: translateY(-20px); 
    transform: translateY(-20px); 
    } 

    100% { 
    opacity: 1; 
    -webkit-transform: translateY(0); 
    transform: translateY(0); 
    } 
} 

@keyframes fadeInDown { 
    0% { 
    opacity: 0; 
    -webkit-transform: translateY(-20px); 
    -ms-transform: translateY(-20px); 
    transform: translateY(-20px); 
    } 

    100% { 
    opacity: 1; 
    -webkit-transform: translateY(0); 
    -ms-transform: translateY(0); 
    transform: translateY(0); 
    } 
} 

.fadeInDown { 
    -webkit-animation-name: fadeInDown; 
    animation-name: fadeInDown; 
} 

.animated { 
    -webkit-animation-duration: 1s; 
    animation-duration: 1s; 
    -webkit-animation-fill-mode: both; 
    animation-fill-mode: both; 
} 

Odpowiedz

5

Zobacz http://css-tricks.com/restart-css-animation/, który omawia dokładnie ten problem.

Myślę, że najczystszym rozwiązaniem jest zawinięcie funkcjonalności usuwania elementu i ponowne włożenie go w tę samą pozycję w drzewie HTML w funkcji globalnej. Następnie, gdy chcesz ponownie uruchomić animację, wystarczy usunąć klasę, wywołać funkcję resetowania (chwytając nowo wstawiony element z wartości zwracanej), a następnie dodać klasę animacji z powrotem, aby ponownie rozpocząć animację.

Na przykład:

function reset($elem) { 
    $elem.before($elem.clone(true)); 
    var $newElem = $elem.prev(); 
    $elem.remove(); 
    return $newElem; 
} // end reset() 

$("#button").click(function() { 
    var $this = $(this); 
    $this.removeClass(); 
    $this = reset($this); 
    $this.addClass("fadeInDown animated"); 
}); 

http://jsfiddle.net/jqm4vjLj/6/

Takie rozwiązanie zapewnia maksymalną szybkość reakcji, ponieważ stary w toku animacja zostanie automatycznie zakończony, gdy element ożywiający jest zniszczona i zaczyna animacja nowo wstawionego elementu natychmiast.

+0

To jest genialne. Świetne odpowiedzi w tym wątku, ale ten fragment kodu przygwoździł dokładnie to, o co prosiłem. Dziękuję Ci. – Tiago

+0

W każdej chwili :) – bgoldst

+2

Pisałem tę samą odpowiedź, ale zostałem pobity! Żadna z pozostałych odpowiedzi nie jest poprawna, ponieważ wszystkie czekają na zakończenie animacji, kiedy @Tiago powiedział, że powinien się zrestartować, nawet jeśli nie jest gotowy. – blex

2

Musisz usunąć klasę po zakończeniu animacji,

ale bezpośrednio korzystające removeClass przyzwyczajenie praca, bo nie pozwala na ukończenie animacji, zamiast tego użyj setTimeout

zobaczyć http://jsfiddle.net/jqm4vjLj/4/

$("#button").click(function() { 

     $("#button").addClass("fadeInDown animated"); 
     setTimeout(function(){ $("#button").removeClass("fadeInDown animated");},100) 
    }); 
0

Problem jest natychmiast usunąć klasę, a następnie dodać klasę, więc po prostu dodaje nowy div z button2 id i na jego kliknij go po prostu usunąć klasy, a następnie ponownie kliknij w przycisk div byłoby animowany.

problem, więc musisz to zrobić po zakończeniu animacji.

$("#button1").click(function() { 
    $("#button").removeClass(); 
}); 

skrzypce jest tutaj: http://jsfiddle.net/jqm4vjLj/5/

+0

Interesujące. To jednak nie pasuje do moich wymagań. Po zresetowaniu użytkownika animacja nie będzie działać. Czy mówisz, że muszę ustawić limit czasu, aby animacja została ukończona przed usunięciem klas? – Tiago

+0

@Tiago Tak, mój zamysł był taki, ale powinieneś przyjąć odpowiedź Aruna, że ​​jest niesamowity. Świetna odpowiedź...! –

10

Znacznie bezpieczniejsze podejście będzie użyć zdarzenia zakończenia animacji jak

$("#button").click(function() { 
 
    $("#button").addClass("fadeInDown animated").one('animationend webkitAnimationEnd oAnimationEnd', function() { 
 
    $("#button").removeClass(); 
 
    }); 
 
});
#button { 
 
    height: 30px; 
 
    width: 120px; 
 
    border: 1px solid black; 
 
} 
 
.animated { 
 
    -webkit-animation-duration: 1s; 
 
    animation-duration: 1s; 
 
} 
 
@-webkit-keyframes fadeInDown { 
 
    0% { 
 
    opacity: 0; 
 
    -webkit-transform: translateY(-20px); 
 
    transform: translateY(-20px); 
 
    } 
 
    100% { 
 
    opacity: 1; 
 
    -webkit-transform: translateY(0); 
 
    transform: translateY(0); 
 
    } 
 
} 
 
@keyframes fadeInDown { 
 
    0% { 
 
    opacity: 0; 
 
    -webkit-transform: translateY(-20px); 
 
    -ms-transform: translateY(-20px); 
 
    transform: translateY(-20px); 
 
    } 
 
    100% { 
 
    opacity: 1; 
 
    -webkit-transform: translateY(0); 
 
    -ms-transform: translateY(0); 
 
    transform: translateY(0); 
 
    } 
 
} 
 
.fadeInDown { 
 
    -webkit-animation-name: fadeInDown; 
 
    animation-name: fadeInDown; 
 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
 
<div id="button"></div>

+0

Ach, wydaje mi się, że tego właśnie szukałem. Czy byłbyś tak uprzejmy, aby wyjaśnić, dlaczego metoda duplikowania .removeClass() przed i po animacji? – Tiago

+0

@Tiago zapomniałem go usunąć ... nie jest wymagane –

+0

Dziękuję @Arun za wspaniałą odpowiedź, ale zdecydowałem się pójść z sugestią bgoldst. Dokładnie to, czego szukałem. – Tiago

0

może to jest dobre rozwiązanie dla swojego problemu:

https://jsfiddle.net/d2c16fk7/3/

w waszym Javascript klas .animation i .fadeInDown dodano do #button a potem trzeba było tych klas i nie można go dodać ponownie .

0

Najprostszym rozwiązaniem dla mnie jest rozpoczęcie procesu reflow przed dodaniem klasy. Możesz to zrobić na przykład przez "zmień" szerokość elementu. Myślę, że proces ponownego przepływu jest szybszy dla przeglądarki, a następnie ponownego wczytywania węzłów. I prostsze pod względem kodowania. w jQuery:

$(this) 
    .removeClass('myAnimation') 
    .width('auto') // the magic 
    .addClass('myAnimation') 
0

Działa to dla mnie, od github animate.css:

animateCss: function (animationName) { 
    var animationEnd = 'webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend'; 
    $(this).addClass('animated ' + animationName).one(animationEnd, function() { 
     $(this).removeClass('animated ' + animationName); 
    }); 
}