jQuery hover animation - how to stop properly on m

2019-08-25 18:34发布

问题:

My problem is that when I move mouse quickly over square element and then go out with my cursor it sometimes doesn't finish the "mouseout" part of hover function

My HTML:

<div id="wrapper">
    <div id="o1" class="square"></div>
    <div id="o2" class="square"></div>
</div>

CSS

#wrapper {
    width: 100px;
    height: 100px;
    position: relative;
}
.square {
    width: 100px;
    height: 100px;
    position: absolute;
}
#o1 {
    background: red;
}
#o2 {
    background: blue;
    display:none;
}

Javascript:

$(function(){
    var o1 = $("#o1");
    var o2 = $("#o2");
    $('#wrapper').hover(function() {
        o1.fadeOut(400,function () {
            o2.fadeIn(400);
        });
    }, function() {
        o2.fadeOut(400,function () {
            o1.fadeIn(400);
        });
    });
});

jsFiddle: http://jsfiddle.net/TQ37t/

I have tried using stop() with different parameter on different places in my code but without success. Thanks

回答1:

The easiest solution I came up with was to make sure all the queues were stopped before adding any new animations:

var o1 = $("#o1");
var o2 = $("#o2");
$('#wrapper').hover(function() {
    o2.stop(true, true);
    o1.stop(true, true);
    o1.fadeOut(400,function () {
        o2.fadeIn(400);
    });
}, function() {
    o1.stop(true, true);
    o2.stop(true, true);
    o2.fadeOut(400,function () {
        o1.fadeIn(400);
    });
});

Note that order matters when stopping the queues. Consider the following sequence:

    o1.fadeOut(400,function () {
        o2.fadeIn(400);
    });
    o2.stop(true, true); // at this point, o1 can still queue a new animation onto o2
        // at this point, o1 might finish fadeOut() and begin o2.fadeIn()
    o1.stop(true, true); // We should have stopped this one first


回答2:

Let's assume that o1 is visible and o2 is hidden. If we quickly hover in and out, the following happens:

  • o1 begins to fade out
  • o2 begins to fade out - finishes instantly, already hidden
  • o1 is told to fade in, as a result of o2 fading out
  • o2 is told to fade in, as a result of o1 fading out

What you get is both shapes being visible at the same time. This then causes further inconsistencies later.

What you need to do is have a flag which you set on mouseover/mouseout, which defines whether the mouse is over the #wrapper or not. You also have similar fadeIn/fadeOut instructions, just like you have now. But for the callback, run a function that reads the flag and determines which object needs to be faded in.

$(function(){
    var o1 = $("#o1");
    var o2 = $("#o2");
    var over = false;
    choose = function() {
        if (over) {
            o2.fadeIn(400);
        } else {
            o1.fadeIn(400);
        }
    }
    $('#wrapper').hover(function() {
        over = true;
        o1.fadeOut(400,choose);
    }, function() {
        over = false;
        o2.fadeOut(400,choose);
    });
});

JSFiddle: http://jsfiddle.net/TQ37t/2/



回答3:

Because there are two different queues running at the same time, getting them to stop was a problem. One solution I came up with was to create a single queue that could be controlled, stopped, etc.. The Javascript looks like this:

var o1 = $("#o1");
var o2 = $("#o2");
var wrapper = $('#wrapper');

function funcToFadeInOutDequeue(jq, isIn) {
    if (isIn) {
        return function() {
            jq.fadeIn(400, function() {
                wrapper.dequeue();
            });
        };
    } else {
        return function() {
            jq.fadeOut(400, function() {
                wrapper.dequeue();
            });
        };
    }
}

wrapper.hover(function() {
    wrapper.stop(true);
    wrapper.queue( funcToFadeInOutDequeue(o1, false) );
    wrapper.queue( funcToFadeInOutDequeue(o2, true) );
}, function() {
    wrapper.stop(true);
    wrapper.queue( funcToFadeInOutDequeue(o2, false) );
    wrapper.queue( funcToFadeInOutDequeue(o1, true) );
});

See the fiddle...



回答4:

This link below should help you to start from something:

http://archive.plugins.jquery.com/project/Pause-Resume-animation


回答5:

Stop actually takes care of the problem (if this is the effect you are after):

$(function(){
var o1 = $("#o1");
var o2 = $("#o2");
$('#wrapper').hover(function() {
    o1.fadeOut(400,function () {
        o2.fadeIn(400);
    });
}, function() {
    o1.stop();
    o2.fadeOut(400,function () {
        o1.fadeIn(400);
    });
});

}); ​

http://jsfiddle.net/adam_gajzlerowicz/TQ37t/3/



标签: jquery hover