I have a jQuery function that looks like this:
$.get(urlCall, function (data) {
$('#divId').children().fadeOut("slow", function() {
$('#divId').append(data);
$('#divId').fadeIn("slow");
});
});
The problem is that it is calling the append and fadeIn lines once for EACH child under '#divId'. I was expecting the line
$('#divId').children().fadeOut("slow", function() {
to fade out all children and then execute the function() a single time. But since it's executing the function() once for each child, I'm appending a lot of lines that I don't want appended.
I'm sure that there must be a way to say, "fade out all children, and then do X once", but I can't seem to figure out how to do it.
Help?
I have a jQuery function that looks like this:
$.get(urlCall, function (data) {
$('#divId').children().fadeOut("slow", function() {
$('#divId').append(data);
$('#divId').fadeIn("slow");
});
});
The problem is that it is calling the append and fadeIn lines once for EACH child under '#divId'. I was expecting the line
$('#divId').children().fadeOut("slow", function() {
to fade out all children and then execute the function() a single time. But since it's executing the function() once for each child, I'm appending a lot of lines that I don't want appended.
I'm sure that there must be a way to say, "fade out all children, and then do X once", but I can't seem to figure out how to do it.
Help?
Share Improve this question asked Oct 17, 2013 at 16:25 barbajoebarbajoe 5475 silver badges15 bronze badges3 Answers
Reset to default 8you can use .promise()
$('#divId').children().fadeOut("slow").promise().done(function() {
$('#divId').append(data);
$('#divId').fadeIn("slow");
});
The .promise() method returns a dynamically generated Promise that is resolved once all actions of a certain type bound to the collection, queued or not, have ended.
By default, type is "fx", which means the returned Promise is resolved when all animations of the selected elements have pleted.
For the the downvoter
Demo: Fiddle
Why not just separate the fading and the appending? So it would be
$.get(urlCall, function (data) {
$('.someElement').each(function(){
$('.fadeElement').fadeIn();
});
$('.otherElement').append(data)
});
The only way to reliably do this is to make your own function that keeps track of how many animations have pleted, and pares against the number of original animations. Something like:
var target = $("#divId"),
children = target.children();
$("#trigger").on("click", function () {
toggleFadeAll(children, function () {
$("#message").fadeToggle();
});
});
function toggleFadeAll(els, callback) {
var counter = 0,
len = els.length;
els.fadeToggle(function () {
if (++counter === len) {
callback.call(null);
}
});
}
DEMO: http://jsfiddle/jbE3C/
(this will obviously need to be adjusted based on what animating you actually want to happen)
The toggleFadeAll
will call the callback provided when all fadeToggle
animations have pleted.
Using .promise()
fails (doesn't execute the desired callback at the right point in time) when there are other animations possibly happening to the elements.