Expanding/collapsing javascript menu

In this post I'll show you how to create an expanding/collapsing menu like Slashdot left menu used to be, using the YUI library and Dav Glass YUI effects widget.

Preview of the script we are going to build.

The HTML markup for our menu is :

  1.  
  2. <div id="menu">
  3. <h1 id="menu-title">Menu</h1>
  4. <div id="menu-links">
  5. <li>Home</li>
  6. <li>About</li>
  7. <li>CSS</li>
  8. </ul></div>
  9. </div>
  10.  

We use 2 div tags, one for holding the menu itself and the other one which contains the links in an unordered list and 1 h1 tag for the title.

The CSS for the menu :

  1.  
  2. /** width of the menu */
  3. #menu{
  4. width: 180px;
  5. }
  6.  
  7. /** the main title */
  8. #menu h1{
  9. line-height: 35px;
  10. color: #fff;
  11. /** simulate link */
  12. cursor: pointer;
  13. font-weight: bold;
  14. /** background image will change when menu expands/collapses */
  15. background: #666 url(images/block-arrow-expanded.gif) no-repeat scroll 30px 13px;
  16. }
  17.  
  18. /** the links */
  19. #menu-links li{
  20. line-height: 35px;
  21. border-bottom:1px solid #ddd;
  22. background-color: #eee;
  23. }
  24.  

Please pay attention to the background for the #menu h1. It contains the image, which will change when the menu collapses or expands. When the menu collapses we'll be using the block-arrow-collapsed.gif image and when the menu expands we'll be using the block-arrow-expanded.gif image. You can find the images in the sample demo file in the images directory.

To do the collapsing/expanding effects, we need to include the following javascript files beforehand :

  1.  
  2. <!-- js -->
  3. <script type="text/javascript" src="http://yui.yahooapis.com/combo?2.5.2/build/yahoo-dom-event/yahoo-dom-event.js&2.5.2/build/animation/animation-min.js"></script>
  4. <script type="text/javascript" src="js/tools-min.js"></script>
  5. <script type="text/javascript" src="js/effects-min.js"></script>
  6.  

We use Dav Glass YAHOO.Tools package and his effects widget along with yahoo-dom-event-animation aggregate file which are hosted on Yahoo servers.

Finally the javascript to do the magical stuff goes like that :

  1.  
  2. <script type="text/javascript">
  3. YAHOO.util.Event.addListener('menu-title', 'click', function(){
  4. if(YAHOO.util.Dom.getStyle('menu-links', 'display') == 'block'){
  5. new YAHOO.widget.Effects.BlindUp('menu-links', {seconds: 0.2});
  6. YAHOO.util.Dom.setStyle('menu-title', 'background-image', 'url(images/block-arrow-collapsed.gif)');
  7. }
  8. else{
  9. new YAHOO.widget.Effects.BlindDown('menu-links', {seconds: 0.2});
  10. YAHOO.util.Dom.setStyle('menu-title', 'background-image', 'url(images/block-arrow-expanded.gif)');
  11. }
  12. });
  13. </script>
  14.  

In line 3 of the above listing, we wait when the user clicks on the menu-title container and we check the display attribute of our links. If the links are not currently displayed then we display them by using Dav's BlindDown effect with a duration of 0.2 seconds ;-).

  1.  
  2. new YAHOO.widget.Effects.BlindDown('menu-links', {seconds: 0.2});
  3.  

We also change the background image for the menu title by using the YAHOO.util.Dom.setStyle method:

  1.  
  2.  
  3. YAHOO.util.Dom.setStyle('menu-title', 'background-image', 'url(images/block-arrow-expanded.gif)');
  4.  

If the links are visible then we do the contrary, i.e we use the BlindUp effect and use the collapsed gif as background image.

Download sample demo

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • StumbleUpon
  • Mixx
  • Ma.gnolia
  • Technorati
  • Netvouz
  • Reddit
  • Propeller
  • Slashdot
  • DZone

33 Comments to “Expanding/collapsing javascript menu”

  1. vijayan 18 July 2008 at 5:06 am #

    Rien compris!!!! Merci quand meme si t’as fait un truc sympa…mais vraiment…rien capté !!!!

  2. asvin 18 July 2008 at 5:30 am #

    o moins tone essaye compran ;-)

  3. Dav Glass 20 July 2008 at 6:46 am #

    Nice article!!

  4. asvin 20 July 2008 at 9:43 pm #

    thanks Dav

  5. shinshuri 11 August 2008 at 7:03 pm #

    Dave:

    Is it possible to create the same menu effect using the tag rather than the and tags?

    Thanks!

  6. shinshuri 11 August 2008 at 7:04 pm #

    Dave, Ok my last comment dis not post correctly.

    I was asking if I could create the menu using a DIV tag rather than the UL and il tags.

    Thanks!

  7. asvin 11 August 2008 at 10:13 pm #

    Shinshuri,

    In fact, it’s Asvin not Dav. ;-) Yes, you can use DIV tags instead of the list. Makes no difference, it should work no problem, you’ll just have to modify the stylesheet. Let me know if you want a helping hand.

  8. shinshuri 11 August 2008 at 10:18 pm #

    Hey thanks a bunch. I’ll let you know if I do need help.

  9. shinshuri 12 August 2008 at 3:04 am #

    Asvin:

    I think I’m gonna need some help on trying to implement this expand and collapse method in my code using the DIV tag instead of the List tags. I’d like to take you up on the offer to help me.

    Also, once the .js file is implemented will there be issues of having to access Yahoo’s server to run this in the client internal to my organization?

    Let me know Thanks!

  10. ShinShuri 12 August 2008 at 10:41 pm #

    Hi Asvin:

    Can you help me with coding the DIV tag in the expand/collapse menu? Or maybe entertain some questions, etc.

    Thanks,

    Shin

  11. asvin 12 August 2008 at 10:49 pm #

    Shin,

    Sure will help you, just give me till tomorrow, i’am overloaded at work ;-)
    Don’t worry will help u

  12. asvin 13 August 2008 at 8:42 pm #

    Shin,

    check out this demo which doesn’t use any LI :
    http://htmlblog.net/demo/yui-menu-slashdot/div.html

    Concerning including the yahoo libraries, no problem, you can download them and extract them to your internal web server.
    Download it here :
    http://sourceforge.net/project/downloading.php?group_id=165715&filename=yui_2.5.2.zip

    Let me know if it’s OK for you.

  13. [...] expand/collapse menu script: On HTMLBlog.net, Asvin Balloo writes in to "show you how to create an expanding/collapsing menu like Slashdot left menu used to be, [...]

  14. Prashant Raju 23 August 2008 at 12:04 pm #

    When you double click on the arrow the div doesn’t appear – it may be a bug and the only fix is to refresh.

  15. Prashant Raju 25 August 2008 at 8:23 am #

    Why did you not approve my comment about the bug?

  16. asvin 25 August 2008 at 9:31 am #

    Yeah seems like a bug, will try to correct it ;-) was overloaded with spam comments over the weekend, Akismet didn’t detect them. ;-)

  17. asvin 25 August 2008 at 10:35 am #

    Prashant

    I’ve decreased the number of seconds for the blind effects and it seems ok, it’s an ugly hack but it seems ok though.

  18. marcell 27 August 2008 at 7:55 pm #

    Nice Thx

  19. SergiuGothic 28 August 2008 at 7:32 pm #

    hello, great tutorial, but when i enter the page, menu is espanded, how i can make to be collapsed?

  20. asvin 29 August 2008 at 2:20 pm #

    thanks Sergiu,
    If you want the menu to be collapsed after page load, you can add a listener which calls the function after page load. You must modify the javascript to this :

    var updateMenu = function(){
    if(YAHOO.util.Dom.getStyle(‘menu-links’, ‘display’) == ‘block’){
    new YAHOO.widget.Effects.BlindUp(‘menu-links’, {seconds: 0.01});
    YAHOO.util.Dom.setStyle(‘menu-title’, ‘background-image’, ‘url(images/block-arrow-collapsed.gif)’);
    }
    else{
    new YAHOO.widget.Effects.BlindDown(‘menu-links’, {seconds: 0.01});
    YAHOO.util.Dom.setStyle(‘menu-title’, ‘background-image’, ‘url(images/block-arrow-expanded.gif)’);
    }
    };

    YAHOO.util.Event.addListener(‘menu-title’, ‘click’, updateMenu);
    YAHOO.util.Event.addListener(window, ‘load’, updateMenu);

    Check out this link for demo :
    http://htmlblog.net/demo/yui-menu-slashdot/folded.html

  21. SergiuGothic 29 August 2008 at 5:04 pm #

    thank you a lot, asvin, it works now :)

  22. asvin 30 August 2008 at 3:42 pm #

    no problem Sergiu, my pleasure ;-)

  23. soman 15 September 2008 at 4:49 pm #

    Hi

    thanks for this. I m noob in web design field. It will help me.

    thanks

  24. david 2 October 2008 at 11:20 pm #

    This is great js. Could you help me out on the most efficient way to impliment more than one of these menus on a single page though? Right now everything relies on ID tags and a repeated javascript code with the new id tag stuck in there each time. I’m new to js, so I’m wondering if there is a better way of having one lump code that can determine which one is being clicked and expand that instead of needing a new function for each menu.

  25. asvin 9 October 2008 at 1:44 pm #

    Hi David,
    Don’t worry I haven’t forgotten you, I’am kinda busy these days with my motherboard fried at home, connection problems, will help you

  26. [...] Recent public urls tagged “util” → Expanding/collapsing javascript menu [...]

  27. Jesse 1 December 2008 at 3:31 pm #

    Thanks asvin, works great :) just hope there’s no super humans using my site that click faster than 0.1 seconds.

    David, I simply added a second function in the html page and labeled my second group as id=”menu-title2″ and id=”menu-links2″.

    replace this with the old

    YAHOO.util.Event.addListener(‘menu-title’, ‘click’, function(){
    if(YAHOO.util.Dom.getStyle(‘menu-links’, ‘display’) == ‘block’){
    new YAHOO.widget.Effects.BlindUp(‘menu-links’, {seconds: 0.1});
    } else{ new YAHOO.widget.Effects.BlindDown(‘menu-links’, {seconds: 0.1}); }
    });
    YAHOO.util.Event.addListener(‘menu-title2′, ‘click’, function(){
    if(YAHOO.util.Dom.getStyle(‘menu-links2′, ‘display’) == ‘block’){
    new YAHOO.widget.Effects.BlindUp(‘menu-links2′, {seconds: 0.1});
    } else{ new YAHOO.widget.Effects.BlindDown(‘menu-links2′, {seconds: 0.1}); }
    });

  28. Sukdev Garai 1 December 2008 at 5:05 pm #

    It is nice and helpfull example.

  29. zap 16 January 2009 at 11:34 am #

    Hey,

    Thanks so much! This will really help me in my project..

    One more thing…

    ..I totally have no idea how to do it but I am hoping you could help me on how to create search engines..

    please mail me.. thx!

  30. Salsan Jose 24 February 2009 at 5:20 pm #

    It seems good.
    I was looking a menu like this.
    Thank you.

  31. [...] bad apple This stuff kills relevancy. During a recent UA test, we had a user in anger and disbelief, ‘your search [...]

  32. Oleh 3 July 2009 at 6:20 am #

    To say the true, I’m disappointed because of last hour was a waste of time. I was trying to put this menu to work. Even it was not ready to just include to existing website because of many reasons including using such a general name as “menu” for IDs and CSS that just kills all existing design, in the end I got final disappointment. It does not allow to have multiple top menu items? Unbelievably hard, non-working solution.

  33. Hammad 7 July 2009 at 8:34 am #

    Awesome code, thanks for sharing.


Leave a Reply