animowanie addClass / removeClass za pomocą jQuery

225

Korzystam z jQuery i jQuery-ui i chcę animować różne atrybuty na różnych obiektach.

Aby wyjaśnić problem tutaj, uprościłem go do jednego diva, który zmienia kolor z niebieskiego na czerwony, gdy użytkownik na niego najeżdża.

Jestem w stanie uzyskać pożądane przeze mnie zachowanie animate(), jednak robiąc to, style, które animuję, muszą znajdować się w kodzie animacji, a więc są oddzielne od mojego arkusza stylów. (patrz przykład 1 )

Alternatywą jest użycie addClass()a removeClass(), ale nie udało się odtworzyć dokładnie zachowanie, które mogę dostać z animate(). (patrz przykład 2 )


Przykład 1

Rzućmy okiem na kod, który mam z animate():

$('#someDiv')
  .mouseover(function(){
    $(this).stop().animate( {backgroundColor:'blue'}, {duration:500});
  })
  .mouseout(function(){
    $(this).stop().animate( {backgroundColor:'red'}, {duration:500});
  });

wyświetla wszystkie poszukiwane przeze mnie zachowania:

  1. Animuje płynnie między czerwonym a niebieskim.
  2. Brak „kolejkowania” animacji, gdy użytkownik szybko porusza myszką do i z div.
  3. Jeśli użytkownik przesunie mysz do środka / do środka, gdy animacja jest nadal odtwarzana, zostanie ona ułatwiona między obecnym stanem „w połowie” a nowym stanem „celu”.

Ale ponieważ zmiany stylu są zdefiniowane w, animate()muszę tam zmienić wartości stylu i nie mogę po prostu wskazywać mojego arkusza stylów. To „fragmentaryczne” definiowanie stylów bardzo mnie niepokoi.


Przykład 2

Oto moja bieżąca najlepsza próba użycia addClass()i removeClass(zauważ, że do działania animacji potrzebujesz jQuery-ui):

//assume classes 'red' and 'blue' are defined

$('#someDiv')
  .addClass('blue')
  .mouseover(function(){
    $(this).stop(true,false).removeAttr('style').addClass('red', {duration:500});
  })
  .mouseout(function(){
    $(this).stop(true,false).removeAttr('style').removeClass('red', {duration:500});
  });

Pokazuje to zarówno właściwość 1., jak i 2. moich pierwotnych wymagań, jednak 3 nie działa.

Rozumiem powód tego:

Podczas animacji addClass()i removeClass()jQuery dodaje element do stylu tymczasowego, a następnie zwiększa odpowiednie wartości, dopóki nie osiągną wartości podanej klasy, i dopiero wtedy faktycznie dodaje / usuwa klasę.

Z tego powodu muszę usunąć atrybut stylu, w przeciwnym razie, jeśli animacja zostanie zatrzymana w połowie, atrybut stylu pozostanie i trwale nadpisze wartości klas, ponieważ atrybuty stylu w znaczniku mają większe znaczenie niż style klas.

Jednak po zakończeniu animacji nie dodano jeszcze nowej klasy, więc dzięki temu rozwiązaniu kolor przeskakuje do poprzedniego koloru, gdy użytkownik porusza myszą przed ukończeniem animacji.


Idealnie chcę, aby móc zrobić coś takiego:

$('#someDiv')
  .mouseover(function(){
    $(this).stop().animate( getClassContent('blue'), {duration:500});
  })
  .mouseout(function(){
    $(this).stop().animate( getClassContent('red'), {duration:500});
  });

Gdzie getClassContentpo prostu zwróci zawartość podanej klasy. Kluczową kwestią jest to, że w ten sposób nie muszę przechowywać definicji stylów w dowolnym miejscu, ale mogę przechowywać je w klasach w arkuszu stylów.

Johannes
źródło
1
Jakie wersje IE potrzebujesz obsługiwać? Czy byłbyś zadowolony z IE9? Czy potrzebujesz wsparcia niższego?
tw16
1
Szczerze mówiąc, wcale nie dbam o IE. Wszystko to zostało przetestowane tylko w przeglądarkach webkit (safari / chrome).
Johannes,
jak getClassContentto wygląda
sreginogemoh

Odpowiedzi:

311

Ponieważ nie martwisz się o IE, dlaczego po prostu nie używaj przejść css w celu zapewnienia animacji i jQuery do zmiany klas. Przykład na żywo: http://jsfiddle.net/tw16/JfK6N/

#someDiv{
    -webkit-transition: all 0.5s ease;
    -moz-transition: all 0.5s ease;
    -o-transition: all 0.5s ease;
    transition: all 0.5s ease;
}
tw16
źródło
14
Stan na dzień 2015-06-12 jest obsługiwany w - IE 10+ - Chrome 26+ - FireFox 16+ - Safari 6.1+ - Opera 12.1+ -webkit, -moz, -o jest wymagany tylko w przypadku starszych przeglądarek. Prawdopodobnie możesz to pominąć, aby zaoszczędzić trochę miejsca.
clst
3
@clst Wolę kompatybilność wsteczną ze starymi przeglądarkami niż oszczędność kilku bajtów miejsca.
Arman H
95

Inne rozwiązanie (ale wymaga jQueryUI, jak zauważył Richard Neil Ilagan w komentarzach): -

addClass, removeClass i toggleClass akceptuje również drugi argument; czas trwania przejścia z jednego stanu do drugiego.

$(this).addClass('abc',1000);

Zobacz jsfiddle: - http://jsfiddle.net/6hvZT/1/

Omar Tariq
źródło
28
Zauważ, że wymaga to interfejsu użytkownika jQuery. jQuery po wyjęciu z pudełka nie obsługuje animacji animacji dla xxxClass()funkcji.
Richard Neil Ilagan
@Richard Neil Ilagan: Dziękujemy za powiadomienie. Naprawdę mi tego brakowało.
Omar Tariq,
4
Czy możesz wskazać, który plik do pobrania i dołączyć do pliku .html, abym mógł używać jQueryUI tylko do xxxClassanimacji w ten sposób?
azotan sodu
[jqueryui.com] (jqueryui.com) @sodiumnitrate
joe_young
1
To rozwiązanie również nie animuje w taki sam sposób jak Slide () lub Animate (). Wartość milisekund to opóźnienie, które nie jest animacją.
Solona Armstrong,
38

Możesz użyć interfejsu użytkownika jquery switchClass, oto przykład:

$( "selector" ).switchClass( "oldClass", "newClass", 1000, "easeInOutQuad" );

Lub zobacz to jsfiddle .

by0
źródło
1
-1. Nie spełniłeś ograniczeń 1, 2 i 3 wymienionych w oryginalnym poście. W szczególności switchClass źle radzi sobie z wymaganiami 2 i 3.
Johannes
12

Potrzebujesz tylko rdzenia efektów interfejsu użytkownika jQuery (13 KB), aby umożliwić czas trwania dodawania (tak jak wskazał Omar Tariq)

Patrick
źródło
5

Patrzyłem na to, ale chciałem mieć inną szybkość przejścia dla wejść i wyjść.

Tak właśnie skończyłem:

//css
.addedClass {
    background: #5eb4fc;
}

// js
function setParentTransition(id, prop, delay, style, callback) {
    $(id).css({'-webkit-transition' : prop + ' ' + delay + ' ' + style});
    $(id).css({'-moz-transition' : prop + ' ' + delay + ' ' + style});
    $(id).css({'-o-transition' : prop + ' ' + delay + ' ' + style});
    $(id).css({'transition' : prop + ' ' + delay + ' ' + style});
    callback();
}
setParentTransition(id, 'background', '0s', 'ease', function() {
    $('#elementID').addClass('addedClass');
});

setTimeout(function() {
    setParentTransition(id, 'background', '2s', 'ease', function() {
        $('#elementID').removeClass('addedClass');
    });
});

To natychmiast zmienia kolor tła na # 5eb4fc, a następnie powoli powraca do normy w ciągu 2 sekund.

Oto skrzypce

Tj Gienger
źródło
2

Chociaż pytanie jest dość stare, dodaję informacje, których nie ma w innych odpowiedziach.

OP używa stop (), aby zatrzymać bieżącą animację po zakończeniu zdarzenia. Jednak użycie odpowiedniej kombinacji parametrów z funkcją powinno pomóc. na przykład. stop (prawda, prawda) lub stop (prawda, fałsz), ponieważ dobrze wpływa to na kolejkowanie animacji.

Poniższy link ilustruje wersję demonstracyjną, która pokazuje różne parametry dostępne w funkcji stop () i różnice między nimi a wykończeniem ().

http://api.jquery.com/finish/

Chociaż PO nie miał problemów z używaniem JqueryUI, dotyczy to innych użytkowników, którzy mogą spotkać się z podobnymi scenariuszami, ale nie mogą używać JqueryUI / także muszą obsługiwać IE7 i 8.

Anurag
źródło