Preventing queuing during multiple .animation events - javascript

$(this).animate({'backgroundColor':'red'},600)
.animate({'color':'#fff'},600);
How can I make both .animate events happen at the same time instead of the second one waiting for the first one to complete?

By specifying them in the same animate call:
$(this).animate({
'backgroundColor':'red',
'color':'#fff'
},600);

You should be able to specify multiple things that change in your animate statement.
$(this).animate({
'backgroundColor':'red',
'color':'#fff'
} ,600);
It's right there in the documentation for .animate().

Related

Properly animate multiple elements with Jquery

Probably I didn't choose the best title for my question, sorry for that.
I'm pretty new with jQuery, hence with animations.
I'm just experimenting with It, but now I have a problem.
The script works like I want, but It seems a bit "buggy", I bet my code isn't optimized, at all... Plus I may be using a wrong way to achieve what I want.
One button is triggering the script (Its not supposed to be like that at the end, but momentarily I'm using this button to trigger the script), it works like a "toggle" and every time I click on "Show", a bunch of HTML is shown and two animations run:
$(".achievement_container").hide(300).show(); //shows the whole container
$(".glow").fadeIn(100).fadeOut(800); // First "brightening" effect
This one shows the whole "frame", while another animation runs for a lighting effect:
$(".ach_hover").css("left", "0px").css("opacity", "1").animate({
left: "252px",
opacity: "0"
}, 1100);
You can see a "working" example here:
http://jsfiddle.net/Frondor/6EA6W/
My problem appear after I click the "Show" button many times, the $(".ach_hover") animation start to fail and it doesn't appear, at all...
I'm not satisfied with the way I wrote this last animation, at least I think there might be a better and "standard" way to achieve this.
So I would really appreciate any suggestion from jQuery experts to "optimize" my script, and avoid any buggy behavior on it.
Thanks in advance
Try using jQuery .stop()
Stop the currently-running animation on the matched elements.
$(".ach_hover")
.css({
"left": "0px",
"opacity": "1"
})
.stop()
.animate({
left: "252px",
opacity: "0"
}, 1100);
Fiddle

Run two functions in the exact same time

I want to slideUp() a div, and when its sliding up, I want to move it down by animate() - in the exact same time .
what I have done so far :
ln = jQuery("Selector");
ln.slideUp(1500, function() {
ln.animate({top: '150px'}, 'slow');
var Html = jQuery('#last' + id1).html() + jQuery('#last' + id2).html();
ln.html(Html);
});
But it slides up first, and then moves down 150px.
I want to call these two functions (slideUp and animate ) in the exact same time, I want to know is it possible or not?
Or does my problem have an easier way to solve ?
P.S : I think this kind of questions has been asked before, like this, but Its not my answer if you read it completely.
You can do this by using .animate() for both operations and just specifying both changes with properties that you pass to animate. The slideup can be done by specifying a final height of 0 for animate. Using this single animation, jQuery will run both changes together as part of the same animation sequence.
ln.animate({top: '150px', height: 0}, 'slow');
Working demo: http://jsfiddle.net/jfriend00/kKsa4/

jQuery wave animation on row of icons

I have a row of icons on my page and i want to create a wave animation effect when user hovers over them with the cursor.
I'm using this basic code for starters:
$('#icons > li')
.hover(function() {
$(this).animate({
'top': (-1 * hover_distance)
}, hover_speed);
}, function() {
$(this).animate({
'top': 0
}, hover_speed);
})
;
And it looks OK. But there is one issue: when you move your cursor frantically over the icons, the animation queue for every icon is becoming filled with lots of actions (up, down, up, down, up, down, etc) and icons is going up and down lots of times even if you stop to interact with the icons.
I want my icons to complete only one cycle (up and down) and then stop the animation. I'm looking for a most elegant (short, simple, light) solution for this.
PS: And you can't just use stop() because it will prevent the "wave effect" (i.e. when you move your cursor with one fast stroke over the icons and they move up and down in response, like a real wave).
PPS: Here's the JS-Fiddle:
http://jsfiddle.net/nZqLy/3/
You can use .stop() before the animations to stop the current animation or .stop(true) to cancel all animations in the queue. http://jsfiddle.net/nZqLy/9/
$('#icons > li').hover(function() {
$(this).stop(true).animate({
'top': (-1 * hover_distance)
}, hover_speed);
}, function() {
$(this).animate({
'top': 0
}, hover_speed);
});
I upvoted the answer by #jimjimmy1995, but just to provide an alternative way of doing the same animation which will be faster and more efficient:
$('#icons').on({
mouseenter:function(){
$(this).stop().animate({top:(-1*hover_distance)},hover_speed);
},
mouseleave:function(){
$(this).stop().animate({top:0},hover_speed);
}
},'li');
The only differences are:
The use of .on() is more transparent, but also allows for more extensibility (you can add more on events later, like mousemove or something, if you want)
Delegation of all li from #icons rather than making #icons > li the selector means the animation binding is only applied once, rather than many times (one time for each li) - this is the most important of the three changes
Using the native DOM name rather than the string (top vs 'top') is a best practice. It makes no difference for non-hyphenated words, but when you start dealing with marginTop vs 'margin-top' it makes a difference.
UPDATE
Found the solution:
$('#icons').on({
mouseenter:function(){
if(!$(this).is(':animated')){
$(this).animate({top:(-1*hover_distance)},hover_speed);
}
},
mouseleave:function(){
$(this).animate({top:0},hover_speed);
}
},'li');
Using the :animated selector checks if the item is in progress of being animated. The if logic will only perform the animation if it is not.
jsFiddle to prove it.

.animate infinite loop

I am interested in a solution for jQuery .animate infinite loop break method.
$(element).mouseover(function() {
$(this).animate({ opacity: 1 }, duration, customFunc);
}).mouseout(function() {
});
And question now is how to break this loop? e.g within a mouseout event?
I can do it easily with setInterval and clearInterval but is there a way to it with .animate function?
Use the .stop method:
http://api.jquery.com/stop/
I assume you want to immediately stop the currently running animation?
$(element).mouseover(function() {
$(this).animate({ opacity: 1 }, duration, customFunc);
}).mouseout(function() {
$(this).stop();
});
You could stop the animation using .stop()
http://api.jquery.com/stop/
You might want to use .stop(true, true) to clear the queue and jump to the end of the animation
You can use .data() to store a flag of if you should animate anymore
http://api.jquery.com/jQuery.data/
Add an IF in your customFunc before you invoke animate again to check the flag of whether or not you should animate. That way you won't refire due to any other callbacks. In your mouseover you should set the flag to be enabled again.
If what you are experiencing is an effect where the animation queues up as your mouse enters and leaves the element repeatedly and continues to repeat the animation over and over several times after your mouse has left the element and not returned - I would recommend the jquery hoverflow plugin for you.
http://www.2meter3.de/code/hoverFlow/

jQuery's stop() seems to be blocking animations that haven't been queued yet

How does jQuery's stop() actually work?
If you look here (http://jsfiddle.net/hWTT6/), when you hover over the main blue box it should fade to red, and when you hover off it should fade back. The problem is it will completely fade to red (and then back to blue) even if the mouse has hovered off before the first fade was complete. The problem can more clearly be seen with the slide effect. Hover over the slide "button" and the main box will slide to blue, hover off, it will slide back. But try hovering on and off and on and off, before the first animation has completed. You'll see that all four animations are carried out. I included both examples here to show it is not just a problem with one effect or something.
I thought this would be easily fixed by adding a stop before the animations, as shown commented out in the code. But, if I do this the current animation will stop and the following one will never start. Almost as though stop is blocking an animation that is occurring after the call to stop.
What am I missing here?
Thanks.
You are missing that .stop() accepts two arguments. Both boolean, indicating:
- clearQueue (first)
- jumpToEnd (second)
So by calling $('#foo').stop( true, true ).doSomeOtherStuff() you should get your desired goal.
Reference: .stop()
The problem is the CSS is getting messed up by stopping at arbitrary points.
The fadeIn(), fadeOut(), slideUp() and slideDown() move from the current state to a new one and then revert to that - not to the original CSS.
You need to fix the CSS back in to a usable state to continue with after the .stop(), or more clearly specify the animation targets.
As the others have said, you can get the CSS to the correct position, by ensuring that when you stop the animation, it jumps to the end of it, rather than leaving everything in an arbitrary state.
UPDATE:
Take a look at the code in this update of your demonstration: http://jsfiddle.net/hWTT6/5/
It might not be exactly how you want it to perform, but the trick, if you do not want the animation to run its course, is to get the animation back in to a state that it can continue from in the way in which you desire.
$(function() {
$('#fade')
.mouseenter(function() {
$('#fg_fade').stop().animate({ 'opacity': 0 }, 'slow', function() {
$('#fg_fade').css('height', '100%');
});
})
.mouseleave(function() {
$('#fg_fade').stop().animate({ 'opacity': 1, 'height': '100%' }, 'slow');
});
$('#slide_fire')
.mouseenter(function() {
$('#fg_fade').stop().animate({ 'height': 0 }, 'slow', function() {
$('#fg_fade').css('opacity', 1);
});
})
.mouseleave(function() {
$('#fg_fade').stop().animate({ 'height': '100%' }, 'slow', function() {
$('#fg_fade').css('opacity', 1);
});
});
});
You could set the stop() options to (true, true) so that you cancel all events in cue and jump to the end of the previous animation. look at the fiddle:http://jsfiddle.net/hWTT6/4/
The stop method can be called in the following difference ways:
.stop(true);
//Same as:
.stop(true, false); //Empty the animation queue only
//Or
.stop(true,true); // Empties the animation queue AND jumps to the end
//Default
.stop()
//Same as
.stop(false,false);
There may be a better way using .animate instead: Demo Here
$(function() {
$('#fade')
.mouseenter(function() {
$('#fg_fade').stop().css('height', '10em').animate({'opacity' : '0'}, 'slow');
})
.mouseleave(function() {
$('#fg_fade').stop().css('height', '10em').animate({'opacity' : '1'}, 'slow');
});
$('#slide_fire')
.mouseenter(function() {
$('#fg_fade').stop().css('opacity', '1').animate({'height' : '0'}, 'slow');
})
.mouseleave(function() {
$('#fg_fade').stop().css('opacity', '1').animate({'height' : '10em'}, 'slow');
});
});
This way the animation stops when you want it to and still runs the next animation.
The problem with doing .stop then slideUp/slideDown or fadeIn/fadeOut is that the animation can end prematurely and keep an incorrect height/opacity.
The problem is caused by the way fadeIn, fadeOut etc. work. You may expect them to fade between 0 and 1. However, in reality they fade between 0 and whatever the "baseline" opacity is. You can see this here:
http://jsfiddle.net/hWTT6/7/
You'll notice I set the initial opacity to .5. Now when I call fadeIn it does not fade all the way in to 1 it fades to my baseline of .5. Your problem occurs when you stop the animation prematurely, the "baseline" becomes whatever the opacity is at the time it is stopped. Now when you call fadeIn on mouseleave it tries to fade to this new baseline and finds it is already there. You can see this illustrated by going here:
http://jsfiddle.net/hWTT6/8/ (original, but with .stop)
If you place your mouse over slide and then remove it half-way through the animation, it will stop in the middle. Now place your mouse back over slide and wait for the animation to complete. If you now remove your mouse, you will see that it slides back down to the place where the first animation was stopped. That is because this is the new "baseline".
The way that you would solve this is actually to replace fadeIn, fadeOut, etc. with a more explicit animation. For instance, use fadeTo to tell it to fade between 0 and 1:
http://jsfiddle.net/hWTT6/6/
Notice that since I am telling it to fade to 0 or 1 everything works. A similar thing could be done to replace slideUp and slideDown using animate.

Categories

Resources