Search code examples
jqueryuser-interfacefunctionjquery-animatetogglebutton

jQuery animation glitch: functions fire in wrong order when mousing across to quickly


NOTE: I didn't write the script in question, my collegue did. Just volunteering to get some input on this for us. Please pardon incorrect terms or descriptions that sound like a noob; I'm not a scripting guy, I'm an HTML/CSS guy.

The page in question:

http://cure.org/curekids/kenya/2010/02/joseph_muchiri/

A screenshot of the issue:

ck-dash-tab.jpg

The issue:

When you look at the page, you'll see a toolbar sort of dash at the top of the page, but just below the site header (its the piece that says "CUREkids").

When you hover over any area of that toolbar there is a small green tab on the left that animates out from behind it (its the piece with the question mark on it). When clicked, the tab toggles open a descriptive Slidedeck interface. So far all is well.

The problem is that if you mouse across the toolbar too quickly, there is a screwy glitch that causes the jQuery rules to fire in a strange way that results in the tab coming out from behind, but going back in overtop of the toolbar.

Additional details:

The way the script works is that the tab is hidden behind the toolbar by default, and the jQuery first animates it left to come out away from the toolbar, then changes the z-index to bring it actually over top of the toolbar element for maximum usability and clicking area on the tab. All this happens on mouseOver. On mouseOut the reverse occurs (z-index changed to lower than the toolbar, and then animates right back to where it was located).

My thoughts

I think there must be an issue with how the script is written that possibly could be tweaked so that when the mouseOver event happens so quickly it doesn't result in the overlap bug.

All help is appreciated.


Solution

  • On the function you defined for mouseleave, add .stop(true, true) before you change the z-index back to -1.

    $("#what-tag").stop(true, true).css("z-index", "-1");

    Check out http://api.jquery.com/stop/

    The first true passed to .stop(true, true) will remove all queued animations. The second true is the key in this situation - it basically jumps to the end of the function you defined for mouseenter and fires its callback immediately. In this case, by using .stop(true, true), you ensure that the z-index will always be set to 1 before setting it to -1.

    I think what is currently happening is that it's setting the z-index to -1 before the mouseenter callback function fires.

    Edit:

    Unrelated - you should also look into caching your jquery selectors into variables. You are calling $("#what-tag") six times in this hover method. If you define a variable above the hover method like this: var $whatTag = $("#what-tag") and replace the references inside the hover method, it will work faster.