Nick
Nick

Reputation: 2551

jQuery - Mouseleave not firing when moving mouse quickly

There are a few answers to similar questions, but none that are working for me while still giving me the desired effect, or none that I understand. So any help or guidance would be great

Here's a fiddle: http://jsfiddle.net/csoh1vzb/

Essentially what happens is when you hover over the cells quickly, the mouseleave function doesn't run and I'm left with the active state.

I've "half fixed" this, but it's still not as I would like it to be.

Adding this to mouseenter fixes the problem on the next hover:

$('.cell .hover').fadeOut();
$('.cell span').animate({ "marginTop" : "500px" });

(Not really a fix)

Any help would be great!

Upvotes: 5

Views: 3142

Answers (3)

Michael Christensen
Michael Christensen

Reputation: 195

Personally the first answer above is probably simpler and thus a better answer. But I like this because the code seems a bit cleaner overall. HTML:

<div class="cell"> <a href="" class="hover" title="ONE"><span>ONE</span></a>

</div>
<div class="cell"> <a href="" class="hover" title="TWO"><span>TWO</span></a>

</div>

CSS:

.cell {
    width: 200px;
    height: 200px;
    background: #f00;
    float: left;
    display: block;
    overflow: hidden;
    position:relative;
}
.hover {
    width: 200px;
    height: 200px;
    background: #000;
    text-align: center;
    position: absolute;
    top:-200px;
}
.hover span {
    display: inline-block;
    padding: 10px 20px;
    font: bold 12px arial;
    font-style: italic;
    text-transform: uppercase;
    background: #222;
    border: 2px solid #fff;
    color: #fff;
}

JavaScript:

(function ($) {
    $('.cell').on('mouseenter', function () {
        $(this).find('span').stop().animate({
            "marginTop": ($(this).innerHeight() / 2 - 19) + "px"
        });
        $(this).find('.hover').stop().animate({
            "top": 0
        });
    }).on('mouseleave', function () {
        var $this = $(this);

        $(this).find('.hover').stop().animate({
            "top": "-200px"
        });
        $(this).find('span').animate({
            "marginTop": "0px"
        });
    });
}(jQuery));

Upvotes: 0

user4467065
user4467065

Reputation: 141

Whenever possible, it is always better to avoid the use of javascript and prefer using css rules.

You can easily replace your html generation and your fade animation using basic html and css, as you can see on this jsfiddle

Writing fully your html :

<a href="" class="cell cell-01" title="ONE">
    <div class="hover"><span>ONE</span></div>
</a>
<a href="" class="cell cell-02" title="TWO">
    <div class="hover"><span>TWO</span></div>
</a>

And defining most of the rules in your css :

.cell {width: 200px; height: 200px; background: #f00; float: left; display: block; overflow: hidden;}

.cell:hover .hover {
        display:inline-block;
        opacity: 1;
        transition: opacity .25s ease-in-out;
        -moz-transition: opacity .25s ease-in-out;
        -webkit-transition: opacity .25s ease-in-out;
}

.hover {
    display:inline-block;
    width: 200px; 
    height: 200px; 
    background: #000; 
    text-align: center;
    opacity: 0;
        transition: opacity .25s ease-in-out;
        -moz-transition: opacity .25s ease-in-out;
        -webkit-transition: opacity .25s ease-in-out;
}

.hover span {display: inline-block; padding: 10px 20px; font: bold 12px arial; font-style: italic; text-transform: uppercase; background: #222; border: 2px solid #fff; color: #fff;}

And you can easily reduce the size of your javascript, making the entire thing more stable and fast.

(function ($) {
    $('.cell').on('mouseenter', function (){
        var $this = $(this);
        $(this).find('span').stop(true, false).animate({ "marginTop" : ($(this).innerHeight() / 2 - 19) + "px" });
    }).on('mouseleave', function (){
        var $this = $(this);        
        $(this).find('span').animate({ "marginTop" : "500px" });
    });
}(jQuery));

Upvotes: 2

baao
baao

Reputation: 73211

The problem is not the not fired mouseleave, the problem you are facing is that the animation takes 400ms (the default animation duration) to complete, which means that the animation is overriding the mouseleave css change directly after it has been applied when you leave the field within say 300ms

To avoid this, you need to stop the animation.

$('.cell span').stop();
$('.cell .hover').fadeOut();

Should do the trick.

As a Sidenote, if you're doing animations with javascript, better change to velocity.js which is far faster than jQuery's animate.

Upvotes: 3

Related Questions