可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
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/