0

I have a list where some items have sub navigation:

  <ul role="menu">
    <li role="menuitem">
      <a href="#" class="clearfix">Top Level</a>
    </li>
    <li class="slidedown open" role="menuitem">
      <a href="#" class="clearfix">Top Level</a>
      <span class="slidedown-toggle">Show Sub Menu</span>
      <!-- Subnav -->
      <ul class="list-reset nav-sub" role="menu">
        <li role="menuitem">
          <a href="#">Second Level</a>
        </li>
        <li role="menuitem">
          <a href="#">Second Level</a>
        </li>
        <li role="menuitem">
          <a href="#">Second Level</a>
        </li>
      </ul>
    </li>
  </ul>

I have this script, which calculates the height of the subnav <ul> when the .slidedown-toggle is clicked and then changes it to 0 depending on the parent <li> having the class 'open' which is toggled.

$(document).ready( function(){ 

  var $slidedownToggle = $('.nav-sidebar .slidedown-toggle');

  $slidedownToggle.click(function () {

    var $slidedown = $(this).parent('.slidedown'); // Get the container item
    var $subnav = $(this).siblings('.nav-sub'); // Get the ul that needs to slide up/down

    var totalHeight = 0; // Calculate the height required (in px) to show all <li>'s
    $subnav.find('li').each(function() {
      totalHeight += $(this).outerHeight(true);
    });

    // Toggle 'open' class on the parent <li>
    $slidedown.toggleClass('open');

    // Set the appropriate height
    if ($slidedown.hasClass('open')) {
      $subnav.css({height: totalHeight + 'px'});
    } else {
      $subnav.css({height: '0px'});
    }

  });

});

The problem I have is that sometimes the class 'open' has already been added the <li class="slidedown"> because when you are on a 'subnav' page I want the menu expended to show where you are. Because I set height: auto in the CSS for .slidedown.open, the height isn't animated (I'm aware of the whole slideup using max-height and I don't want that) when you first click the slidedown-toggle of 'open' items.

Easiest way to see what I'm on about is to look at the JSBIN. Click the second 'show menu' and it's slides up and down nicely. Click the first one and the first click doesn't slide (because of the height auto). How can I fix that? Maybe set the height on click first and then set it to 0?

http://jsbin.com/poxiy/2/edit

davidpauljunior
  • 8,238
  • 6
  • 30
  • 54

2 Answers2

2

It is a nasty hack, that works... on ready handler assign a height to the opened subnav

$('.nav-sidebar .slidedown.open .nav-sub').height(function(){
    return $(this).height();
})

Demo: Fiddle

Another solution is discussed in the below posts

Community
  • 1
  • 1
Arun P Johny
  • 384,651
  • 66
  • 527
  • 531
  • Can you explain why that's a "nasty hack"? I know about the other CSS solutions, but they fail when you have varying length subnavs which in some instances are very long. Perhaps using the standard `.show() and .hide()` would be better, but I found the animation jerky at times compared to the CSS animation. – davidpauljunior Mar 20 '14 at 00:48
  • @davidpauljunior (not an expert in css animation) I called it a nasty hack because there could be a more elegant solution and what we are doing is a hack – Arun P Johny Mar 20 '14 at 00:50
0

You could try a hover based menu list - looks super sexy.

HMTL

> <!DOCTYPE html> <html> <head> <script
> src="http://code.jquery.com/jquery-1.9.1.min.js"></script> <ul
> id="nav">     <li><a href="#">Parent 01</a></li>  <li><a href="#"
> class="selected">Parent 02</a>        <ul>            <li><a href="#">Item
> 01</a></li>           <li><a href="#" class="selected">Item 02</a></li>
>           <li><a href="#">Item 03</a></li>        </ul>       <div
> class="clear"></div>  </li>   <li><a href="#">Parent 03</a>   <ul>
>       <li><a href="#">Item 04</a></li>        <li><a href="#">Item 05</a></li>
>       <li><a href="#">Item 06</a></li>        <li><a href="#">Item 07</a></li>
>   </ul>                   <div class="clear"></div>   </li>   <li><a href="#">Parent
> 04</a></li> </ul>   </body> </html>

Java

$(document).ready(function () { 

    $('#nav li').hover(
        function () {
            //show its submenu
            $('ul', this).stop().slideDown();

        }, 
        function () {
            //hide its submenu
            $('ul', this).stop().slideUp();         
        }
    ); 

});
Srulis
  • 5
  • 7