2013-04-17 8 views
8

Używam animacji cieniowania CSS +. Moja klasa cieniujący definiuje się następująco:Animacja CSS nie uruchamia się ponownie po zresetowaniu klasy

.shader{ 
-webkit-filter :custom(url(v.vs) mix(url(f.fs) multiply destination-over), 200 200); 
-webkit-animation-name: test; 
-webkit-animation-duration: 2s; 
-webkit-animation-iteration-count: 1 
} 

Próbuję włączony/wyłączony stylów (shader + Animacja) dynamicznie przy użyciu jQuery przez $('#holder').addClass('shader'); i $('#holder').removeClass('shader');

Jednak dziwne jest to, kiedy zresetować class (np. wywołanie addClass po removeClass), tylko moduł cieniujący zostanie ponownie zastosowany, ale animacja nie (Zainteresowałem się zdarzeniem AnimationStart, aby zobaczyć, kiedy zaczyna się moja animacja). Ktoś wie, dlaczego tak jest i jak mogę go rozwiązać?

Edytuj: Dodałem uproszczoną wersję kodu JSfiddle here. Zasadniczo ponownie stosuję animację do elementu div, ale animacja jest wywoływana tylko za pierwszym razem.

+2

Czy próbowałeś zachować właściwości animacji w oddzielnej klasie, która nigdy nie została usunięta? – bfavaretto

+0

mmmm nie, ale nie sądzę, że to pomogłoby, ponieważ mam tylko 1 iterację i wywołuję removeClass po animacjiOd zdarzenia – Discombobulous

+0

Czy możesz napisać [jsFiddle] (http://jsfiddle.net/), dzięki czemu możemy mieć lepszy wygląd – apaul

Odpowiedz

4

Myślę, że to wymyśliłem. Według this animacja css nie może zostać zastosowana do tego samego węzła dwukrotnie (nawet jeśli masz inną animację!). Musiałem więc sklonować węzeł, usunąć oryginał i dodać sklonowany węzeł.

+0

Różne animacje na pewno działają w Chrome. – dmi3y

23

Problem polega na tym, że mimo usunięcia, a następnie ponownego zastosowania animowanej klasy, robi się to w trakcie jednej, blokującej funkcji. Kiedy twoja funkcja się kończy, pojawia się silnik renderujący, że nic się nie zmieniło.

Jednym z rozwiązań (tym, który wybrałeś) jest sklonowanie elementu i zniszczenie oryginału. To jest w porządku, ale gdybyś miał jakiekolwiek powiązania zdarzeń z oryginalnym elementem (myślę), oni również zostaną zniszczeni.

Innym rozwiązaniem jest usunięcie animowanej klasy z elementu, a następnie zawijanie kodu, który ponownie stosuje klasę wewnątrz wywołania setTimeout() z bardzo małym opóźnieniem, np.

$('#holder').removeClass('shader'); 
setTimeout(
    function(){$('#holder').addClass('shader')} 
    , 1); 

mam manipulowane swoją jsfiddle używać tego podejścia: http://jsfiddle.net/HuFBN/7/

+2

To jest poprawna odpowiedź. Dodatkowe punkty wyjaśniają, dlaczego ten hack jest potrzebny ("Kiedy twoja funkcja się kończy, pojawia się silnik renderujący, że nic się nie zmieniło"). –

+0

To zadziałało dla mnie. Podoba mi się również to, że można łatwo dostosować opóźnienie w tym podejściu, tak jak wtedy, gdy powinno zacząć się od nowa. dzięki! – blackhawk

3

Według 2011 article na css-tricks.com, wywołując reflow między usuwanie i dodawanie klasę będzie ponownie uruchomić animację. Przykład (gadatliwy):

$('#holder').removeClass('shader'); 
$('#holder').offsetWidth = $('#holder').offsetWidth; // triggers reflow 
$('#holder').addClass('shader'); // restarts animation 
+0

Wygląda na to, że łamie to tryb javascript. – Adam

+0

@Adam Nie widzę, jak to łamie tryb ścisły. Czy masz więcej szczegółów? – feklee

0

Spróbuj użyć tego właśnie po zastosowaniu animacji - biorąc pod uwagę, że "e" to animowana elementem:

e.outerHTML = e.outerHTML; 
1

Trzeba odtworzyć swój element.

function resetAnimation(jqNode) { 
    var clone = jqNode.clone(); 
    jqNode.after(clone); 
    jqNode.remove(); 
    jqNode[0] = clone[0]; 
} 
+0

To bardzo przydatna metoda resetowania animacji. Dzięki. – sentenza

0

Zdecydowanie trzeba usunąć klasę zawierającą animację, a następnie dodać ją ponownie. Powinno również działać bez .offsetWidth. To zadziałało dla mnie. Aby wykonać tę operację, należy wykonać

.