Memory-​Effekt in jQuery-Animationen

Von in javascript, jquery, netzthetik

Das jQuery-​Framework bie­tet Funk­tio­nen, mit deren Hil­fe und nur weni­gen Zei­len Code ansehn­li­che Ani­ma­tio­nen erzeugt wer­den kön­nen. Dabei tre­ten mit­un­ter aber auch uner­war­te­te Effek­te auf. Einen sol­chen möch­te ich hier beschrei­ben: Den Memory-​Effekt bei der Ver­wen­dung der jQuery-​Funktion .hover() in Kom­bi­na­ti­on mit einer Animation.

Stel­len wir uns ein DOM-​Objekt vor, das wir, wenn sich der Maus­zei­ger über dem Objekt befin­det, ani­mie­ren möch­ten. Dabei soll es sich um ein paar Pixel nach oben bewe­gen. Ent­fernt sich die Maus wie­der vom Objekt, soll es sich in die Aus­gangs­po­si­ti­on zurück­be­we­gen. Hier bie­tet sich die Funk­ti­on .hover() an. In die­sem Arti­kel wird spä­ter neben­bei gezeigt, wie die Funk­ti­on ein­ge­setzt wird. Ver­wen­det man sie in Kom­bi­na­ti­on mit einer Ani­ma­ti­on, wird man beim Tes­ten auf fol­gen­des Ver­hal­ten auf­merk­sam wer­den: Wenn man rasch mehr­mals die Maus über das Objekt hin­weg bewegt, führt das Objekt die Ani­ma­tio­nen nicht nur dann aus, wenn die Maus die hover-​Funktion aus­löst, son­dern das Objekt scheint sich die durch­ge­führ­ten Trig­ger zu “mer­ken” und die Ani­ma­tio­nen so lan­ge und so oft aus­zu­füh­ren, wie die Maus zuvor das Objekt über­fah­ren hat. Das mag auf den ers­ten Blick amü­sie­ren, der Benut­zer wird davon jedoch irri­tiert sein. Weil die­ser Memory-​Effekt etwas schwie­rig zu beschrei­ben ist, habe ich ein Video erstellt, das das Ver­hal­ten etwas bild­li­cher beschreibt:

Ich möch­te hier auch ein Live-​Beispiel zum Aus­pro­bie­ren anbieten:

 

  • Tab 1
  • Tab 2
  • Tab 3

 

Die­sem Bei­spiel liegt fol­gen­der JavaScript-​Code zugrunde:

$(document).ready(function(){

    $("ul li").hover(
        function(){
            $(this).animate(
            {
                marginTop: "-20px"
            },
            "fast" );
        },
        function(){
            $(this).animate(
            {
                marginTop: "0px"
            },
            "fast");
        }
    );

});

Das Vor­ge­hen ist ein­fach: Dem Objekt, hier jedem Lis­ten­ein­trag, wird ein Event-​Handler ange­hängt (Zei­le 3). Fährt man mit der Maus über das Objekt, erfolgt eine Ani­ma­ti­on des Mar­gins um 20px nach oben (ers­te Funk­ti­on, Zei­le 4), ver­lässt die Maus das Objekt, erfolgt die Ani­ma­ti­on nach unten (zwei­te Funk­ti­on, Zei­le 11). Dabei führt Java­Script die Ani­ma­ti­on auf Gedeih und Ver­derb aus, egal, was in der Zwi­schen­zeit pas­siert. Denn ein wei­te­rer Mou­seo­ver bin­det erneut das Event auf das Objekt und Java­Script führt es aus, wenn die letz­te Ani­ma­ti­on been­det wur­de. Und dar­in liegt auch schon die Lösung des Pro­blems: Bei erneu­tem Trig­gern der Funk­ti­on muss zuerst die mög­li­cher­wei­se lau­fen­de Ani­ma­ti­on gestoppt wer­den. Sehen wir uns zunächst den Code dazu an:

$(document).ready(function(){

    $("ul li").hover(
        function(){
            $(this).is(":animated").stop();
            $(this).animate(
            {
                marginTop: "-20px"
            },
            "fast" );
        },
        function(){
            $(this).is(":animated").stop();
            $(this).animate(
            {
                marginTop: "0px"
            },
            "fast");
        }
    );

});

Jetzt wird in Zei­le 5 und Zei­le 13 abge­fragt, ob das Objekt gera­de ani­miert wird. Wenn dem so ist, wird die Ani­ma­ti­on sofort gestoppt. Damit bekommt das Objekt ein völ­lig ande­res Ver­hal­ten. Pro­bie­ren Sie es aus:

 

  • Tab 1
  • Tab 2
  • Tab 3

 

Hin­weis zur ein­ge­setz­ten Technik:
Die oben ange­führ­ten Bei­spie­le die­nen der Demons­tra­ti­on der The­ma­tik. Das hover-​Event auf die Lis­ten­ob­jek­te zu bin­den ist nicht son­der­lich pra­xis­taug­lich (ver­ein­facht aber die Erklä­run­gen für das eigent­li­che The­ma in die­sem Arti­kel), denn wenn sich durch die Ani­ma­ti­on das Objekt so weit von der ursprüng­li­chen Posi­ti­on weg­be­wegt, dass es nicht mehr unter dem Maus­zei­ger liegt, kommt es zu einem wei­te­ren uner­wünsch­ten Effekt. Bewe­gen Sie hier­zu ein­fach bei einem der obi­gen Bei­spie­le den Maus­zei­ger von unten lang­sam an einen der drei Tabs her­an, bis er den Tab gera­de an der unte­ren Kan­te berührt. Der Tab fängt dann an zu “hüp­fen”. Das liegt dar­an, dass sich eben das Objekt vom Maus­zei­ger weg­be­wegt und von sel­ber durch die Ani­ma­ti­on das mouseout-​Event trig­gert. Dar­um wäre es für die Pra­xis bes­ser, das zu ani­mie­ren­de Objekt mit einem Blocklevel-​Element zu wrap­pen, etwa einem DIV, das den Ani­ma­ti­ons­ra­di­us des zu ani­mie­ren­den Objekts abdeckt. Das hover-​Event bin­det man dann auf den DIV. So hängt die Posi­ti­on des Maus­zei­gers nicht mehr von der Posi­ti­on des zu ani­mie­ren­den Objekts ab. Die­ses Bei­spiel soll vor allem auch zei­gen, wie unter­schied­lich die JavaScript-​Engines der ver­schie­de­nen Brow­ser den Code inter­pre­tie­ren, denn die­ses “Hüp­fen” tritt nicht über­all auf.

Share on LinkedInShare on Redditshare on TumblrShare on StumbleUponDigg thisShare on FacebookGoogle+Tweet about this on TwitterEmail to someone