DeanHyde
DeanHyde

Reputation: 107

Hover/mouseenter event triggers jQuery UI's 'animate' repetitively

So I have a navigation and I'm using jQuery's UI animate to make the list item slide down out of view, change colour, and to then slide back up, revealing the button in a different color.

The problem I'm getting is that whenever I hover over the list item, the hover event is triggered continually until the mouse has left.

Even stranger, is that it appears that the mouseleave event triggers right after the hover event, regardless of whether the mouse has actually left the list item. This happens whether I used hover or mouseenter.

Here's what I have: HTML:

<nav>
    <ul>
        <a href="index.html"><li>Home</li></a>
        <a href="services.html"><li>Services</li></a>
        <a href="portfolio.html"><li>Portfolio</li></a>
        <a href="contact.php"><li>Contact</li></a>
        <a href="about.html"><li>About</li></a>
    </ul>
</nav>

jQuery:

$("nav li").mouseenter(function(){
        $(this).animate({bottom:"-50px"},"fast", function(){$(this).css('background','orange');$(this).css('color','#fff');});
        $(this).animate({bottom:"-0px"},"fast");
    }).mouseleave(function(){
        $(this).animate({bottom:"-50px"},"fast", function(){$(this).css('background','white');$(this).css('color','#333');});
        $(this).animate({bottom:"-0px"},"fast");
    });

CSS:

nav{
float:right;
margin-top:91px;
}
nav ul, nav ul li{
display:inline;
}
nav li{
margin-left:10px;
position:relative;
padding:5px 20px;
color:#A29874;
background-color:#fff;
border-top-right-radius:5px;
border-top-left-radius:5px;
 }

nav a{
position:relative;
text-decoration:none;
 }

I can achieve the effect I'm after if I very slowly bring my mouse into one of the list items, just a few pixels inside. This task, which seems as if it should be relatively easy, is driving me nuts.

I've scoured the net and have tried things such as unbinding the mouseenter event, using a conditional to run the animation only after the mouseleave event has triggered to no avail.

Any suggestions would be greatly appreciated, preferably before I go bald. Thanks!

Upvotes: 2

Views: 1307

Answers (2)

sholsinger
sholsinger

Reputation: 3088

The reason for your problem is that you're moving the element so it is no longer under the mouse. Therefore obviously mouseleave() is triggered. You can avoid this by triggering the animation on hover of the a tag, but target the li with the animation. See: http://jsfiddle.net/aN4g4/50/

Here's your new js:

$("nav a").mouseenter(function(){
    var $li = $(this).find('li');
    $li.stop(true,true).animate({bottom:"-50px"},"fast",
        function(){
            $li.css({'background':'orange','color':'#fff'});
        });
    $li.stop(true,true).animate({bottom:"-0px"},"fast");
}).mouseleave(function(){
    var $li = $(this).find('li');
    $li.stop(true,true).animate({bottom:"-50px"},"fast",
        function(){
            $li.css({'background':'white','color':'#333'});
        });
    $li.animate({bottom:"-0px"},"fast");
});

You may have noticed that the callback function which fires after the animation finished has been optimized a bit. You can pass multiple CSS properties in this way: .css({'prop1':'val1','prop2':val2'}) Also, I have optimized the code so you're not generating a lot of jQuery objects because that is slow. (notice the var $li line.)

Upvotes: 2

Ricardo Binns
Ricardo Binns

Reputation: 3246

try to set yours li as position: relative;

i just "paste" your code and set relative yours <li>

the result was a little funny.

See here: http://jsfiddle.net/aN4g4/47/

Upvotes: 0

Related Questions