animieren von addClass / removeClass mit jQuery

225

Ich verwende jQuery und jQuery-ui und möchte verschiedene Attribute für verschiedene Objekte animieren.

Um das Problem hier zu erklären, habe ich es zu einem Div vereinfacht, der von blau nach rot wechselt, wenn der Benutzer darüber fährt.

Ich kann das gewünschte Verhalten bei der Verwendung animate()erzielen. Dabei müssen sich die zu animierenden Stile jedoch im Animationscode befinden und sind daher von meinem Stylesheet getrennt. (siehe Beispiel 1 )

Eine Alternative ist die Verwendung von addClass()und removeClass()ich konnte das genaue Verhalten, mit dem ich arbeiten kann, nicht wiederherstellen animate(). (siehe Beispiel 2 )


Beispiel 1

Werfen wir einen Blick auf den Code, den ich habe animate():

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

Es zeigt alle Verhaltensweisen an, nach denen ich suche:

  1. Animiert reibungslos zwischen Rot und Blau.
  2. Keine Animation "Überreihen", wenn der Benutzer seine Maus schnell in das Div hinein und aus dem Div heraus bewegt.
  3. Wenn der Benutzer seine Maus während der Wiedergabe der Animation nach außen / innen bewegt, wird zwischen dem aktuellen Status "auf halbem Weg" und dem neuen Status "Ziel" korrekt verschoben.

Da die animate()Stiländerungen jedoch in definiert sind, muss ich die Stilwerte dort ändern und kann nicht einfach auf mein Stylesheet verweisen. Diese "Fragmentierung" der Definition von Stilen stört mich wirklich.


Beispiel 2

Hier ist mein derzeit bester Versuch mit addClass()und removeClass(Beachten Sie, dass Sie jQuery-ui benötigen, damit die Animation funktioniert):

//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});
  });

Dies zeigt sowohl die Eigenschaft 1. als auch die 2. meiner ursprünglichen Anforderungen, jedoch funktioniert 3 nicht.

Ich verstehe den Grund dafür:

Wenn Animieren addClass()und removeClass()fügt jQuery einen temporären Stil auf das Element, und erhöht dann die entsprechenden Werte , bis sie die Werte der bereitgestellten Klasse erreichen, und erst dann wird es die Klasse tatsächlich hinzufügen / entfernen.

Aus diesem Grund muss ich das Stilattribut entfernen. Andernfalls bleibt das Stilattribut erhalten und überschreibt permanent alle Klassenwerte, wenn die Animation auf halber Strecke gestoppt wird, da Stilattribute in einem Tag eine höhere Bedeutung haben als Klassenstile.

Wenn die Animation jedoch zur Hälfte fertig ist, wurde die neue Klasse noch nicht hinzugefügt. Bei dieser Lösung springt die Farbe zur vorherigen Farbe, wenn der Benutzer die Maus bewegt, bevor die Animation abgeschlossen ist.


Idealerweise möchte ich in der Lage sein, so etwas zu tun:

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

Wo getClassContentwürde nur der Inhalt der bereitgestellten Klasse zurückgeben. Der entscheidende Punkt ist, dass ich auf diese Weise meine Stildefinitionen nicht überall aufbewahren muss, sondern sie in Klassen in meinem Stylesheet aufbewahren kann.

Johannes
quelle
1
Welche IE-Versionen müssen Sie unterstützen? Würden Sie mit IE9 zufrieden sein? Oder müssen Sie niedriger unterstützen?
Tw16
1
Ich kümmere mich überhaupt nicht um IE, um ehrlich zu sein. Dies wurde alles nur mit Webkit-Browsern (Safari / Chrome) getestet.
Johannes
Wie getClassContentsieht es aus?
Sreginogemoh

Antworten:

311

Da Sie sich keine Sorgen um den Internet Explorer machen, können Sie einfach CSS-Übergänge verwenden, um die Animation bereitzustellen, und jQuery, um die Klassen zu ändern. Live-Beispiel: 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
quelle
14
Ab dem 12.06.2015 wird dies in - IE 10+ - Chrome 26+ - FireFox 16+ - Safari 6.1+ - Opera 12.1+ -webkit unterstützt, -moz, -o wird nur für noch ältere Browser benötigt. Sie können es wahrscheinlich weglassen, um Platz zu sparen.
Clst
3
@clst, ich würde die Abwärtskompatibilität mit alten Browsern der Einsparung von ein paar Bytes Speicherplatz vorziehen.
Arman H.
95

Eine andere Lösung (aber es erfordert jQueryUI, wie von Richard Neil Ilagan in Kommentaren hervorgehoben): -

addClass, removeClass und toggleClass akzeptieren ebenfalls ein zweites Argument. die Zeitdauer, um von einem Zustand in den anderen zu gelangen.

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

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

Omar Tariq
quelle
28
Beachten Sie, dass hierfür die jQuery-Benutzeroberfläche erforderlich ist. jQuery out of the box unterstützt kein Animations-Tweening für xxxClass()Funktionen.
Richard Neil Ilagan
@ Richard Neil Ilagan: Danke für die Benachrichtigung. Ich habe diesen Punkt wirklich verpasst.
Omar Tariq
4
Können Sie angeben, welche Datei heruntergeladen und in die HTML-Datei aufgenommen werden soll, damit ich jQueryUI nur für xxxClassAnimations-Tweening auf diese Weise verwenden kann?
Natriumnitrat
[jqueryui.com] (jqueryui.com) @ Natriumnitrat
joe_young
1
Diese Lösung animiert auch nicht auf die gleiche Weise wie slide () oder animieren (). Der Millisekundenwert ist eine Verzögerung, die keine Animation ist.
Solona Armstrong
38

Sie könnten jquery ui's verwenden switchClass, hier ein Beispiel:

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

Oder sehen Sie diese jsfiddle .

by0
quelle
1
-1. Sie haben die Einschränkungen 1, 2 und 3, die ich im ursprünglichen Beitrag aufgeführt habe, nicht erfüllt. Insbesondere behandelt switchClass die Anforderungen 2 und 3 schlecht.
Johannes
12

Sie benötigen lediglich den jQuery UI- Effektkern (13 KB), um die Dauer des Hinzufügens zu aktivieren (genau wie bei Omar Tariq).

Patrick
quelle
5

Ich habe mich damit befasst, wollte aber eine andere Übergangsrate für In und Out haben.

Das habe ich letztendlich getan:

//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');
    });
});

Dadurch wird die Hintergrundfarbe sofort auf # 5eb4fc geändert und über 2 Sekunden langsam wieder normal.

Hier ist eine Geige

Tj Gienger
quelle
2

Obwohl die Frage ziemlich alt ist, füge ich Informationen hinzu, die in anderen Antworten nicht vorhanden sind.

Das OP verwendet stop (), um die aktuelle Animation zu stoppen, sobald das Ereignis abgeschlossen ist. Die Verwendung der richtigen Mischung von Parametern mit der Funktion sollte jedoch helfen. z.B. stop (true, true) oder stop (true, false), da dies die Animationen in der Warteschlange gut beeinflusst.

Der folgende Link zeigt eine Demo, die die verschiedenen mit stop () verfügbaren Parameter und ihre Unterschiede zu finish () zeigt.

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

Obwohl das OP keine Probleme mit JqueryUI hatte, ist dies für andere Benutzer gedacht, die möglicherweise auf ähnliche Szenarien stoßen, JqueryUI jedoch nicht verwenden können / IE7 und 8 ebenfalls unterstützen müssen.

Anurag
quelle