Mehrere parallele hover()-Animationen vermeiden
Problem
Wir sind alle schon mindestens einmal in diese Falle gelaufen. Sie schreiben so etwas wie:
jQuery('#something').hover( function(){ // coole Animation für jQuery(this) }, function(){ // coole Animation in Ausgangszustand zurückversetzen } );
So könnten Sie zum Beispiel ein Element immer dann vergrößern, wenn der Mauscursor darüber bewegt wird, und es beim Verlassen mit der Maus wieder zurücksetzen.
Alles klappt wunderbar, bis Sie die Maus schnell herein- und wieder herausbewegen und … was passiert da?
Das Element jQuery('#something')
wird plötzlich viele Male
hin- und hergeschaltet, bis die Animation schließlich endet.
Lösung
Die Lösung ist wirklich einfach, aber das Problem taucht so häufig auf, dass ich diese Lösung trotzdem als nützlich ansehe.
Um diesen verrückten Effekt zu vermeiden, müssen Sie einfach alle bestehenden Animationen für das Element abbrechen, bevor Sie eine neue erstellen.
Dazu haben Sie die jQuery-Methode stop()
zur Verfügung. Sie stoppt (wie der
Name schon sagt) die aktuelle Animation und entfernt optional auch
die folgenden.
Diskussion
Beispiel
Ich werde Ihnen ein Beispiel einer Animation
der CSS-Eigenschaft opacity
zeigen,
aber die Lösung funktioniert auch für jede andere Eigenschaft:
jQuery('#something').hover( function(){ jQuery(this).stop().animate({opacity:1}, 1000); }, function(){ jQuery(this).stop().animate({opacity:0.8}, 1000); } );
Dies funktioniert auch für vorgefertigte
jQuery-Animationen wie slideUp()
,
slideDown()
, fadeIn()
und so weiter.
Dies ist das vorherige Beispiel, aber mit einem Fade-Effekt:
jQuery('#something').hover( function(){ jQuery(this).stop().fadeTo( 1, 1000 ); }, function(){ jQuery(this).stop().fadeTo( 0.8, 1000 ); } );
Der Rest
Es kann aber immer noch ein Problem entstehen, wenn man sich in Situationen wie der folgenden befindet:
jQuery('#something').hover( function(){ jQuery(this).stop() .fadeTo( 1, 1000 ) .animate( {height:500}, 1000 ); }, function(){ jQuery(this).stop() .fadeTo( 0.8, 1000 ) .animate( {height:200}, 1000 ); } );
Probieren Sie diesen Code aus und bewegen die Maus sehr schnell, dann wird das Element wieder sehr unschön animiert werden – allerdings nur die Höhe, nicht die Opazität.
Der Grund ist einfach – Animationen werden in jQuery standardmäßig in eine Queue gestellt. Fügen Sie also mehrere Animationen hinzu, werden sie nacheinander ausgeführt.
stop()
stoppt (und
entfernt) standardmäßig nur die aktuelle Animation. In unserem
letzten Beispiel wird nur die Animation der Opazität entfernt
werden, die Animation der Höhe verbleibt aber in der Queue und ist
bereit, sofort ausgeführt zu werden.
Um das zu vermeiden, müssen Sie entweder
stop()
ein weiteres Mal aufrufen oder
als Argument für die Methode true
übergeben. Dadurch sorgt stop()
dafür,
dass auch alle gequeueten Animationen verworfen werden. Unser
Hover-Code sollte also so aussehen:
jQuery('#something').hover( function(){ jQuery(this).stop(true) .fadeTo( 1, 1000 ) .animate( {height:500}, 1000 ); }, function(){ jQuery(this).stop(true) .fadeTo( 0.8, 1000 ) .animate( {height:200}, 1000 ); } );