Reputation: 1022
The problem is a simple one, I know, but I'm having a heck of a time trying to figure it out. I have 8 divs on a page that hold image galleries which start off hidden. When a user clicks on an icon to view a gallery, the first gallery they chose fades in all shiny. But when they choose another, the one they were viewing begins to fade out while the other fades in below it, and then moves up into its correct position as the first div is hidden.
See jsfiddle.
So, my question is apparent:
How do I get the gallery they were viewing to fade out completely before the next one fades into the correct space.
Upvotes: 3
Views: 1611
Reputation: 30099
Your problem is explained by this sentence in the documentation (fadeOut):
If multiple elements are animated, it is important to note that the callback is executed once per matched element, not once for the animation as a whole.
In other words, because you are animating two things, the callback will be called twice. Because one of your divs is already hidden, the fadeOut
completes instantly*, and immediately calls back.
*Instantly completing if already shown/hidden is unique to the show/hide type helper functions. If you constructed your own fade animation it would always take the specified amount of time, regardless of the current state.
You can fix this a couple of ways. The easiest is to chain your fadeOut()
calls inside of each other, instead of calling one on both elements:
$('.icon_one').click(function() {
$('#image_two').fadeOut(function() {
$('#image_three').fadeOut(function() {
$('#image_one').fadeIn();
});
});
});
Because one will usually be hidden already, it will fall through instantly, but the other will take time. Either way, only after both are complete will the fade in happen.
Demo: http://jsfiddle.net/jtbowden/XQnhs/
Of course, with a little change to your HTML, you can do all three with one click handler:
<div id="image_one" class="imageBox" style="background-color:red;height:50px;width:50px"> </div>
<div id="image_two" class="imageBox" style="background-color:blue;height:50px;width:50px"> </div>
<div id="image_three" class="imageBox" style="background-color:yellow;height:50px;width:50px"> </div>
<div data-num="one" class="icon_show">Red</div>
<div data-num="two" class="icon_show">Blue</div>
<div data-num="three" class="icon_show">Yellow</div>
Script:
$('.icon_show').click(function() {
var showID = '#image_' + $(this).data('num');
$('.imageBox:visible').fadeOut(function() {
$(showID).fadeIn(400);
});
});
Demo: http://jsfiddle.net/jtbowden/NAcPW/
The key being that you automatically figure out which one to show based on the link you click. In this case, I do it by storing a number in a data attribute. You could also just use part of the ID, or do it by figuring out the offset using index
and then feeding that into eq
.
Demo: http://jsfiddle.net/jtbowden/NnN58/
There are lots of ways to simplify this code.
Upvotes: 7
Reputation: 10243
This was interesting... I like the way you set up your jsfiddle- it made it easier to play around with. see if this helps.. fadeOuts are bound to more than element. Only fade out the visible one. I think your issue is fadeout is getting called on elements that already faded out.
here is a slight variation on your jsfiddle..
$(function(){
$('#image_two,#image_three').hide();
//1//
$('.icon_one').click(function(){
$('#image_two:visible,#image_three:visible').fadeOut(
function(){
$('#image_one').fadeIn();
}
);
});
//2//
alert("binding");
$('.icon_two').click(function(){
$('#image_one:visible,#image_three:visible').fadeOut(
function(){
$('#image_two').fadeIn();
}
);
});
//3//
$('.icon_three').click(function(){
$('#image_one:visible,#image_two:visible').fadeOut(function(){
$('#image_three').fadeIn();
});
});
});
Upvotes: 3
Reputation: 3465
You can place divs on top of each other with position:absolute;
Working example: http://jsfiddle.net/Ghokun/wnTte/13/
Upvotes: 2
Reputation: 1239
how about replacing
$('#image_one').fadeIn();
with
$('#image_one').delay(500).fadeIn();
and like wise....
Upvotes: 1