jQuery finish slide before next mouseover
I have a list of span tags that fire a mouseover event which updates the src attribute and slides the next im开发者_StackOverflow中文版age in. The problem I am having is that if a user rolls over a number of the controls in quick succession then the animation becomes very jumpy and looks bad. Below is my current code:
$("#list .client").mouseover(function(){
var imgSrc = $(this).attr('rel');
var image1 = $("#clientImage1");
var image2 = $("#clientImage2");
if(image1.is(":visible")){
image2.attr('src', imgSrc);
image2.stop(true, true).show("slide", { direction: "down" }, 400);
image1.stop(true, true).hide("slide", { direction: "up" }, 400);
//image1.hide();
}
else{
image1.attr('src', imgSrc);
image1.stop(true, true).show("slide", { direction: "down" }, 400);
image2.stop(true, true).hide("slide", { direction: "up" }, 400);
}
//console.log("Img Source: " + imgSrc);
});
What I would like to do is add a time delay if there is currently an animation still in progress. I do not want to queue functions, just perform the last one called on the last mouseover. I assume it has something to do with SetTimeout but I am a little confused as to how to acheive this.
Any ideas?
Thanks!
Edit:
Thanks so much for your help, finally got it to work with hoverIntent! The working code:
$(document).ready(function(){
$("#clientImage2").hide();
$("#list .client").hoverIntent(config);
});
var config = {
over: slideShow, // function = onMouseOver callback (REQUIRED)
timeout: 600, // number = milliseconds delay before onMouseOut
out: doNothing // function = onMouseOut callback (REQUIRED)
};
function slideShow() {
var imgSrc = $(this).attr('rel');
var image1 = $("#clientImage1");
var image2 = $("#clientImage2");
if(image1.is(":visible")){
image2.attr('src', imgSrc);
image2.stop(true, true).show("slide", { direction: "down" }, 600);
image1.stop(true, true).hide("slide", { direction: "up" }, 600);
}
else{
image1.attr('src', imgSrc);
image1.stop(true, true).show("slide", { direction: "down" }, 600);
image2.stop(true, true).hide("slide", { direction: "up" }, 600);
}
}
function doNothing(){}
usually when you do animations you want to stop previous animations, so before you do an animation you can insert a .stop(true, true) before the animation (like $("#myelement").stop(true,true).fadeIn()
for example). The first 'true' clears the animation queue for the element, the second 'true' stops the currently running animation.
You could do 2 things.
First, you oculd use the hoverIntent plugin which will ignore quick mouseovers, or you could unbind the mouseover action until the animation is complete.
http://cherne.net/brian/resources/jquery.hoverIntent.html
Edit:
Use unbind as such:
$("#list .client").mouseover(function(){
$("#list .client").unbind('mouseover');
}
Make the function that does all of this a named function instead of anonymous. Then when the animation of the image showing completes. rebind the mouseover function the same way you bind it in the first place
function slideShow() {
$("#list .client").unbind('mouseover');
var imgSrc = $(this).attr('rel');
var image1 = $("#clientImage1");
var image2 = $("#clientImage2");
if(image1.is(":visible")){
image2.attr('src', imgSrc);
image2.stop(true, true).show("slide", { direction: "down" }, 400, function() {
$("#list .client").mouseover(slideShow);
});
image1.stop(true, true).hide("slide", { direction: "up" }, 400);
//image1.hide();
}
else{
image1.attr('src', imgSrc);
image1.stop(true, true).show("slide", { direction: "down" }, 400);
image2.stop(true, true).hide("slide", { direction: "up" }, 400);
}
// binding
$("#list .client").mouseover(slideShow);
精彩评论