views:

141

answers:

3

I see this question asked a lot in the related questions, but my need seems very simple compared to those examples, and sadly I'm just still too new at js to know what to remove...so at the risk of being THAT GUY, I'm going to ask my question...

I'm trying to switch out the div contents in a box depending on the button pushed. Right now I have it working using the animatedcollapse.toggle function, but it doesn't look very good. I want to replace it with a basic fade in on click and fade in new content on next button.

Basic idea:

<div>
<ul>
<li><a href="this will fade in the first_div"></li>
<li><a href="this will fade in the second_div"></li>
<li><a href="this will fade in the third_div"></li>
</ul>
<div class="first_container">
 <ul>
  <li>stuff</li>
  <li>stuff</li>
  <li>stuff</li>
 </ul>
</div>
<div class="second_container">
 <ul>
  <li>stuff</li>
  <li>stuff</li>
  <li>stuff</li>
 </ul>
</div>
<div class="third_container">
 <ul>
  <li>stuff</li>
  <li>stuff</li>
  <li>stuff</li>
 </ul>
</div>
</div>

I've got everything working with the animated collapse, but it's just an ugly effect for this situation, so I want to change it out.

Thanks! Joel

A: 

Looks like toggle supports a speed setting...maybe that would be more elegant?

floyd
The toggle effect is too busy for my needs. I would like to replicate this: http://css-tricks.com/learning-jquery-fading-menu-replacing-content/but I'm too new at this to know how to modify and remove all the extra bits...
Joel
A: 

How about a JQuery fade out - http://docs.jquery.com/Effects/fadeOut and then your callback is a fade in?

..I just saw your link in the comments, that is exactly what they are doing on CSS tricks. Do you have a more specific question?

UPDATE The visible class refers to the div that will be visible...haven't tested this but it should be about right

$('.first_container').click(function(){
    $('.visible').fadeOut(3000,function(){
                this.removeClass('visible');
        $('.first_container').addClass('visible');
        $('.first_container').fadeIn(3000);
    });
})

That is the code to reference your first_container....you can go from there

Tony
it looks great...could you give me a code example if you have time? I've seen those pages, but I just don't know how to make that work for my code above...
Joel
+3  A: 

Joel, I think I understood what you wanted. Does this look right? In the code below I also used a convention where you append js to the class attribute on HTML so you can style your JS bits differently. If JS were disabled, all three tabs would show down in order. However, as long as JS is enabled, your code will display as desired.

You could improve this by dynamically setting the height of the #animators div based on the tallest height of the children, but it was getting complex enough as it was!

I changed your HTML a bit (both for testing and functionality.):

<div>
  <ul>
  <li><a href="#">First</a></li>
  <li><a href="#">Second</a></li>
  <li><a href="#">Third</a></li>
  </ul>
  <div id="animators">
    <div class="container">
     <ul>
      <li>stuff1</li>
      <li>stuff1</li>
      <li>stuff1</li>
     </ul>
    </div>
    <div class="container">
     <ul>
      <li>stuff2</li>
      <li>stuff2</li>
      <li>stuff2</li>
     </ul>
    </div>
    <div class="container">
     <ul>
      <li>stuff3</li>
      <li>stuff3</li>
      <li>stuff3</li>
     </ul>
    </div>
  </div>
</div>

Add this to your CSS:

.js #animators { position: relative; height: 100px}
.js #animators div.container { position: absolute; left: 0; top: 0 }

And use this JavaScript:

<script type="text/javascript">
  document.documentElement.className += " js"; // Add js class to the HTML element
  $(function(){
    var $containers = $("#animators > div").hide();

    $('ul li a').each(function(i,el){
      var idx = i;
      $(this).click(function(e){
        var $target = $containers.filter(':eq(' + idx + ')');
        // Fade out visible div
        if($containers.filter(':visible').not($target).length){
          $containers.filter(':visible').fadeOut();
        }
        // Fade in new div if not already showing
        $target.not(':visible').fadeIn();
        e.preventDefault();
      })
    })
  });
</script>

EDIT Here is an alternate JavaScript block that fadesOut then fadesIn:

<script type="text/javascript">
  document.documentElement.className += " js"; // Add js class to the HTML element
  $(function(){
    var $containers = $("#animators > div").hide();

    $('ul li a').each(function(i,el){
      var idx = i;
      $(this).click(function(e){
        var $target = $containers.filter(':eq(' + idx + ')');
        // Fade out visible div
        if($containers.filter(':visible').not($target).length){
          $containers.filter(':visible').fadeOut(1000, function(){
            $target.not(':visible').fadeIn(1000);
          });
        } else {
          $target.not(':visible').fadeIn(1000);
        }

        e.preventDefault();
      })
    })
  });
</script>
Doug Neiner
the fadeIn should really should be in a callback.
Tony
@Tony if you want it to fadeOut *then* fadeIn, you are correct. I was going for a crossfade.
Doug Neiner
@Doug good point, i wrongly assumed he wanted fade out then fade in. nice solution
Tony
Thanks for doing this work. The sandbox model is doing exactly what I want. For some reason, when I plug this in my code, and I push the first button, it opens the contents of ALL the divs and no other buttons do anything.well I think I know what I did wrong, but my server just went down...:-(
Joel
Works great! Thanks man! now...how do I adjust the fade speed? :-D
Joel
just supply an integer to both the `.fade()` calls. So, `.fade(1000)` is 1 second, etc. You can also use `slow`, `medium`, and `fast` as well. Just pass them as strings.
Doug Neiner
Right on. Thanks so much! This looks great. :-D
Joel
There is a strange thing with the fade. The first fade in is great but then fading out works, but as the fade out happens, the crossfade fade in seems to come in very quick. Can I slow down that "crossfade-fadein"?
Joel
I added an alternate script. Try that and see if it works more like you want.
Doug Neiner
Awesome! Thank you! I look forward to the day that I can look at this code and really understand it.
Joel
Great! I highly recommend the book by Cody Lindley jQuery Enlightenment. Fuel Your Coding has a review and is running a giveaway: http://fuelyourcoding.com/jquery-enlightenment-book-review-and-giveaway/
Doug Neiner
well-I just noticed something strange...the regular nav bars on the page (not part of this script) now don't work when this javascript is there. I can click them, but they don't go anywhere...
Joel
@Joel, I wrote my code based on what you pasted. The UL is not scoped, and as such, would apply to every UL on the page. Just change the first selector as needed `ul#links li a` and then `id="links"` to your UL surrounding your links, etc.
Doug Neiner
ok. I understand. Thank you!
Joel
got it. That's the great thing about this stuff-I just learned a lot from that mistake...Thanks, too, for the book recommendation.
Joel
Happy to help Joel!
Doug Neiner