with Imagination: by Dustin Diaz

./with Imagination

A JavaScript, CSS, XHTML web log focusing on usability and accessibility by Dustin Diaz

DHTML expand and collapse div menu

Saturday, February 12th, 2005

This is another one of those “I’ve seen this done way too often,” and of course, it’s a lot easier than what folks make it. The simple pull out, drop down, expanded and collapsed div (there’s such a variety of names we can call it) is now here for you copy and pasting pleasure.

JavaScript: Element Block Toggle

function switchMenu(obj) {
var el = document.getElementById(obj);
if ( el.style.display != 'none' ) {
el.style.display = 'none';
}
else {
el.style.display = '';
}
}

And there ya have it. View the Block-Toggle Demo in action.

How to collapse all on page ‘load’

If you’re wondering how to collapse any given amount of particular elements, you can simply use this function in combination with the prototype $() dollar function and addEvent:

Prototype dollar $() function

function $() {
var elements = new Array();
for (var i = 0; i < arguments.length; i++) {
var element = arguments[i];
if (typeof element == 'string')
element = document.getElementById(element);
if (arguments.length == 1)
return element;
elements.push(element);
}
return elements;
}

collapse all at page load

function collapseAll(objs) {
var i;
for (i=0;i<objs.length;i++ ) {
objs[i].style.display = 'none';
}
}
function pageLoad() {
collapseAll($('myDiv1','myDiv2','myDiv3'));
}
addEvent(window,'load',pageLoad);

156 Responses to “DHTML expand and collapse div menu”

  1. Jordan

    This is actually a simpler version than what I’ve been using, although I’ve known it only ammounted to this. I just never got around to writing it… mainly because JavaScript isn’t my strong point. My knowledge of it basically ammounts to document.write and other simple document controls. CSS/(X)HTML/XUL is more my forte.

  2. Dustin

    Yep, we were pretty much in the same position…but after all this DOM reading this stuff is really starting to make much more sense.

    It’s great when you start expanding your languages…you can really start to see the similarties.

    In the book “The complete reference: Javascript” ( see sidebar) the author keeps mentioned C and C++ and how similar it is. In my mind, this looks just like PHP’s object model with out dollar ($) signs and method operators (->). Instead it’s no dollar signs and instead of the dash arrow (->) it’s a dot (.).

    Then instead of dealing with different servers interpreting PHP differently, you have to worry about different browsers. lol.

  3. shawna

    Sweet! I just used a toggle on my new blog. Of course I snake some page source and tinkered with it a bit. But it was a nice intor to javascript for me. Something I have, until now, avoided like the plague.

    I just found a new love for switch statements (PHP). Upon the Diaz man’s suggestions. Wow they work nice!

  4. Dustin

    switch is also in the DOM specification. Also available as of JavaScript 1.2

    Heh. but 1.2 was like netscape 4, so we’re all good to go :)

  5. Mary

    Can be made even smaller too.

    I dunno if you allow code tags/posting here, but here’s a shot.

  6. Mary

    One more try.

    <script type=”text/javascript”>
    <!–
    function switchMenu(obj)
    {
    var el = document.getElementById(obj);
    el.style.block = (el.style.display != ‘block’) ? ‘block’ : ‘none’;
    }
    //–>
    </script>

  7. Dustin

    even better. Very nice.

  8. Tony

    The only problem I see with this method is when the user has javascript turned off…there’s no way to see the hidden (collapsed) text. With js off, it should default to all elements displayed, similar to the Christian Heilmann method: http://www.onlinetools.org/tools/domcollapse.php

    Sure, Christian’s method isn’t as short and sweet…but it solves a major usability issue.

  9. Stephan

    Is there a way to formulate the code so that the JavaScript can be applied to a 100-link list, without creating 100 unique IDs?

    Well, if your FAQ is dynamically generated, you can use numbered or array-based IDs. Parctically, you will be modifying only one of the entries.

    I believe that the most common cross-platform way to get the attributes of a block-level element (i.e. div) is through the DOM tree, so I guess you will need it.

  10. Dustin

    whoa, i forgot people comment on old stuff…

    on the issue of having stuff defaulted to be open. I’d rather keep them closed. so, in essense, you can have the javascript close them upon window.onload… but if JS is disabled, they can default to display block. how does that sound as a solution?

  11. Tom

    nice - thanks for sharing :) How would you go about adding an expand/collapse image (in place of ‘Switch it now’) that switches depending upon the state?

  12. Martijn

    Great, this example is just what I needed. thanx!

  13. Chaaban

    how can we turn this thing off by default ?

  14. Dustin Diaz

    you set the elements display to none.

  15. Tim

    This is great just what i was looking for, but with one problem.
    I am using this to expand and collapse a menu but when the page loads all the items are expanded, not what I wanted.
    I have tried setting the display to none in the css file as mentioned above but all that does is hide all the sub menu items.
    Any ideas on how to have the menu appear collapsed to start with?

    Cheers,
    Tim.

  16. Dustin Diaz

    Tim,
    so which is it? Do you want them open or closed… You said you wanted them closed, so you did display:none, and now they’re all closed, what did you expect?

    If you want, you can have another function that does exactly the opposite. Instead of != ‘none’, you could have != ‘block’ - but the problem you’ll run into with that is it will mess up your inline elements. The original function is safer because it just removes the display from your element going back to its original state.

  17. Tim

    I wanted them closed when the page loads, I now have it working.

    my mistake was to put the display:none; in the external css file. This prevented them from being opened.

    by putting style=display:none; in the ul elements i want to switch it now works fine.

    Cheers,
    Tim.

  18. Andy

    Putting style=display:none; as an inline style is fine, but, again, what happens if JS is disabled? Then the submenus are hidden permanently, right?

    So, your suggestion of closing them all on load sounds great. I wrote a function to be performed on load, but I’m having no luck with it..:

    function closeAll() {
    switchMenu("*")
    }

    Yeah, laugh all you want… it works fine if I explicity name the IDs that I need to close, so… um, why can’t I just say “OK, do that to them all”, by putting an asterisk in place of the ID?

    I’m guessing I need to get an array of the IDs on the page (getElementById?), and use a “for” loop to perform the function for them all. Which I had a stab at, but couldn’t, ultimately, get it to work. And, I’ve just noticed that that would hide everything on the page if it did work. Hmmm.

    Any chance of a couple of pointers in the right direction? It’s almost the perfect piece of code for what I’m trying to do, but, like I say, it’d be great to make it default to be closed for JS users and open for those with JS disabled.

  19. Dustin Diaz

    I’m guessing I need to get an array of the IDs on the page

    Or, getElementsByClass() :)

  20. Andy

    Oh, how beautiful. Here’s the final code. I’ve a feeling that it could be done without three separate functions, but, y’know, I’m just happy that it works.

    This link unhides the below line of text. Which won’t be below until you click it.
    Yeah, I’ll be hidden at first, but by clicking the above link, you can unhide me.

  21. Andy

    Hmm. That didn’t work… thought I used the code tags OK.

  22. Dustin Diaz

    Andy, be sure to escape your entities here.
    ‘<’ is ‘&lt;’ and ‘>’ is ‘&gt;’

  23. Alexander

    Whaah! I’m could not get the div menu to appear collapsed on load!

    Could you please give me the full code that shows a collapsed div menu on load?

    Thanks!

  24. Ryan

    I would also like to know how to get the div menu to appear collapsed on load! I’m no good at JS :(

    Thanks.

  25. stroke

    i also would like to know how to make it appear collapsed on page load, so that it could be expanded on click. nice job.

  26. Scott

    Great code thankx… very simple compared to others which are over 100 lines of code… thanx for sharing.

    Quick question though… I’m using it for a FAQ of 24 questions all answers are set to display:none. When a vistors selects the question answers displays. Can you hide open answers before displaying the next selected item?

    Hope I expained that right.

  27. David

    Any chance I can view the code to automatically close all the divs on load and display them all expanded if JS is disabled? I’m not having any luck getting it to work.

  28. chris w

    i also would like to know how to make it appear collapsed on page load, so that it could be expanded on click. nice job.

  29. Dustin Diaz

    Hey guys, I updated this article despite being published almost 10 months ago. I put up an example of how you can collapse page elements after the page has loaded.

  30. Frustrated

    nice code… but what I cannot figure out, is how to call the toggle javascript function from a URL link.

    I’ve managed to figure out how to use links on a page(with the code) which go to anchors to ALSO open/toggle the hidden div. I cannot seem to call that toggle function from a separate page’s navigation link though. Any ideas?

    I figured [[ href=”javascript:toggle(’1′);window.location.xxxx=’url’;” ]] would work (also tried switching the order) but it does not work

    Basically, if anyone has ideas on how to take the user from one page, to another page’s anchor while opening the toggle - I would be very grateful.

    THANKS!

  31. Christoph Awender

    this demo does not make sense to me, why should someone collapse a div?
    I understand if someone wants to expand a div, but why collapse?

    Chris

  32. Dustin Diaz

    Christoph,
    The whole point is show and hide. it’s more or less like a configuration piece. Several people can attest to its usefulness.

  33. DiFFeReNT

    How can I change this script to - in a list of many rows that can be expanded/collapsed - only show one at a time. So if you expand one, it collapses all the others.
    Like the “Non-standard Appearance” on http://javascript.cooldev.com/scripts/cooltree/demos/superdemo/
    Except that script has all the html inside a 20kb javascipt file, plus another js file, so it’s not good for editing. And 20kb seems like an awful lot.

    Thanks,
    DiFFeReNT (Chris L.)

  34. DiFFeReNT

    Oh hey, just noticed my question was already asked…. duh

  35. Sven

    Like a few more people, I dont get the “collapseAll” to work.
    I want to start with all div’s collapsed/closed.
    Can someone give me a simple example.
    Thanks

  36. Kenny

    Worked great first time. Thanks

  37. DiFFeReNT

    Let me rephrase…
    My questions was already asked (by Scott post #26), but not answered.

    Help would be appreciated.

    Thanks,
    DiFFeReNT

  38. mikeymuss

    my hero

  39. Martin Petrov

    I’ve been looking for a similiar menu with Google, and this is probably the best. However I want to ask you all if you have seen a little bit more complicated script.

    Is it possible to remember the state of the content (hidden or visible) for the next you visit the page? Like Gmail where the box for “labels” stays expanded or collapsed when you return to the site.

    Also :) - how can we add a background image (a plus/minus sign) ?

    And lastly :) - if I have a definition list: Switch link

    Content is it possible not to put any id or classes in dd?

    That would be the perfect script.

  40. stashuk

    Is it possible to modify this code so that items are opened and collapsed on hover, not on click?

  41. Sean

    There are zillions of ways to implement expand/collapse and this is one of the best examples i have seen. My problem is how to get the rest of the boxes to move up if they are positioned absolute. I am thinking i need to find a way to walk the dom tree and convert each absolute element’s styles to finding out where the same position would be relative.

  42. Arnold Shore

    var counter=0; // toggle single element - unless you revise this
    var dirs = new Array (’none’, ” );
    function switchMenu(obj) {
    var el = document.getElementById(obj);
    counter++;
    el.style.display = dirs [counter % 2];
    }

  43. Michael

    Ok I’m going to look like a right newbie here (which I am) but i’m having problems getting the collapsed on page load script to work. I can get the original script (top box) to work, do I simply C&P the script in the 3rd box?
    is it possible for you to add a example like the expand on load one that’s posted?
    Thanks

  44. Dustin Diaz

    Michael, are you using the addEvent function that I posted? it’s between the 2nd and 3rd code block.

  45. Andrew

    Hey guys… Very nice stuff.

    Though I wonder, is there a possibility to save the (un)toggled items, so that when for example the end-user refreshes the page, it will show the previously (un)toggled items? Could this be done using Cookies? I’d like to see an example from you guys!! :)

  46. ironcrutchli

    After reading some of these comments; let me just say you are a patient person. ;)

    I just wanted to add, on a side note, that if you want to use this type of script on a table you have to make one small change.

    Because IE does whatever it wants, it will choke on the switch from none to block when used during the drawing of a table.

    Therefore if you use the ids on rows or somesuch simply leave out the “block” and the row will drop to default behavior in effect making it display properly.

    I think I said that all correctly(been a while since I ran into that issue, but it was bleeping frustrating); I am sure someone can correct me if I mistated something.

  47. ironcrutchli

    LOL, nevermind the script by default has the block out.

  48. Dustin Diaz

    Just as an update: You can see the Seven ways to toggle an element which will hopefully be a bit more enlightening.

  49. Ray

    Man, You saved my day!

    Great piece of work!

  50. Bryan

    I’m with Michael, Post #43. I snagged the source from your sample page, but like everyone else, I want it collapsed on open. You tell him to use the AddEvent function, between the 2nd and 3rdCode block, but the 2nd & 3rd codeblock has nothing in it. Since I am a total newbie, I’m not sure where to put these two extra bits of code. So a complete example would be great. You could keep the sample that shows it open, and then another sample with it closed on startup. Most of us newbies can reverse enginer and tweak it.

    Also, the AddEvent link..I kept getting the feeling I should click it and it would add the new elements for me. Kind of a generate the script for you feature. But it just takes me to the home page, so not sure why telling poster number #43 to use the addEvent link is useful.

  51. Dustin Diaz

    Sorry about that, I updated the link to the addEvent function. After you have the function in your file, you’ll be good to go :)

  52. David Cowman

    Ok, This seems to be the best thing since sliced bread! However i cant find a link to a working example or a download that I could play with.

    Simply put im a newb at JS and do not know how to put the snippets of code together.

    Any tohoughts or links would be appreciated .
    David

  53. Pat

    I’m havinog trouble with the collapse on load too. Any chance you could post the complete code. I’ve added all the functions you mention but still it won’t work.

  54. Pat

    Solved! For anyone else having trouble - paste the code from the three windows and the addEvent function code (from the link). If you are using the sample to test then make sure you alter the MyDiv1 in the function pageLoad to myvar.

    And thanks for the code it now works a treat!

  55. Travis Watson

    This is in lieu of post #26 by Scott, and post #33,34,37 by DiFFeReNT.

    I too wanted a menu type system that would collapse all others when it was clicked, so I wrote one.

    It is based on the use and implementation of your getElementsByClass function. It relies heavily on a naming convention for your classes:
    All classes that are collapseable has to have the word “collapse” (with a space between the other words) in the class name. After that, every class that has to be shown together, for instance multiple cells in a table, needs to have the same keyword in their class names. Again, seperate this word from others with a space!

    Now that you have your naming convention, take a look at http://www.dullandgrey.com

    This is an example of what’s going on, and you should really look at http://www.dullandgrey.com/menu.js

    I have explicitly noted what is Dustin’s and what is mine (he wrote lots more than me haha).

    If you have the naming convention, and you use that collective .js file, then you just need to call show(’keyword’) where keyword is a unique term in the class name(s) you wish to show/hide.

  56. Stephen Clark

    Great stuff! Somewhat of a newbie here. So apologies in advance if I’m missing the obvious.

    I want the “expand/collapse” link to display different images, a “+” and a “-”. So if the is collapsed, you would see a “+” icon on the toggle link to indicate that you can expand to see more. When the is expanded, you would see a “-” icon on the toggle link to indicate that the user can close it.

    How do I do that?

    If I’m being dense and missing something, my apologies. But in all examples I’ve seen here, the link text/indicator does not change.

    thanks
    Steve

  57. Nimmi

    To have the links collapsed on Page Load, include style=”display:none” in the div tags. I tried it works for me :-)

  58. Travis Watson

    Naughty Nimmi! What happens if the Javascript is disabled when the user views your page? Voila: all content hidden.

    Just test it out. Use Dustin’s methods. Make the function to show all of them, then add the event call through javascript as well.

    Basically: eliminate all javascript dependencies inside your HTML.

  59. Kate

    Thanks for this example! Very clear and helpful.

  60. Fallon

    Thanks for the code. I love it. One question, though. I’m making a Visual Basic program that displays a webpage inside the program. The webpage contains the code you have here and it works perfectly except that I get a Script Error that states ‘EventCache’ is undefined and asks if I’d like to continue running scripts on the page. I do not get the same error when I load the page into FireFox. IE simply blocks the active content for my security. The code is unusable if one has to decide whether or not to allow ‘possibly harmful active content’ each time the page loads. Is there any way to (A) define EventCache (B) suppress/eradicate the script warnings?

    Thanks much in advance for all your help.

    -Fal

  61. John

    I am trying to use your code within a table element in a MS Frontpage template, and only the first “h2″ collpases and expands. The second appears fully expanded without the function. Is there a trick for doing it within a table ?

  62. johnsee

    I’d just like to add to the chorus of voices wondering if the state can be remembered when another page is navigated to, or the page is refreshed :S

  63. Travis Watson

    johnsee (and others),
    With javascript, you can make your page remember [practically] anything you want it to. All you have to do is use cookies.

    Dustin has, in his top ten list, three functions to get, set, and delete cookies. They are very useful and friendly, but there’s not really any documentation as to how they work:
    http://www.dustindiaz.com/top-ten-javascript/

    I wanted to achieve the same effect and performed a google search. The following page is not really endorsed by me, but it did enable me to get the job done, so I’m passing it along:
    http://www.echoecho.com/jscookies.htm

    Pretty much just use these functions in your onClick events to set the cookie, and then when your page loads, just check to see if they’re set, alterring the state correspondingly.

  64. premier69

    please explain to me how to make this: http://www.dustindiaz.com/basement/block-toggle.html

    non expanded at page load, I just don’t get it.
    Please show me the complete code.

  65. DiFFeReNT

    Thanks a lot Travis! This is perfect!
    Also thanks to Dustin for making javascript (and life) so much simpler…

    By the way, cool new site design.

  66. Amar

    Dustin,
    Much thanks for the clean and uber useful tutorial. :-) I ran into a small problem using the above solution. I have a common header page included across all my pages and the common header page has my pageLoad function (as suggested above). But the actual div tags vary from page to page and having a common pageLoad does not seem to work since the function aborts on encountering the first div tag not found in the current page. Thoughts…?

  67. James

    Amar;

    I just put all the scripts together and it works fine. I, too, want to use this across more than one page with a common header.

    I don’t know if you use a PHP blog/CMS or your site is built in PHP. Regardless, whatever server scripting language you use, you should be able to do a conditional statement, based upon a page number or variable for the page. Then you can either include a piece of javascript or a specific JS file with the right array, based on the page variable. It’s really easy with a platform like Wordpress ….

  68. Chas Devlin

    Great stuff, but please, please, please put examples of this code all in one place. I see some people not understanding which windows to copy (they’re all seperate) and how that code differs from the basic example up top. It’s also a tad confusing not knowing what to copy to create certain functions.

    Sorry for the whining!

  69. jeff

    Still can’t figure the damn thing out.

  70. Gigi

    Hello Everyone,
    My website side menu has been driving me mad for the past couple of months and I don’t know how to fix it. I’m using dreamweaver on a MAC. I would like to have my submenu become visible when main menu titles are clicked and the grey arrow on the side to turn downward and for the background to turn green. Also when another main menu tile is clicked the previous submenu should become invisible and the arrow should return to it original closed state.

    Someone please help.

  71. Robomilk

    Very handy script! I use it on my blog now for the calendar feature! Saw you in .net magazine! Thanks!

  72. Mike C

    Here is the complete code for the menu that is collasped by default, including the example above:

    Switch menu

    function switchMenu(obj) {
    var el = document.getElementById(obj);
    if ( el.style.display != ‘none’ ) {
    el.style.display = ‘none’;
    }
    else {
    el.style.display = ”;
    }
    }

    function addEvent( obj, type, fn ) {
    if (obj.addEventListener) {
    obj.addEventListener( type, fn, false );
    EventCache.add(obj, type, fn);
    }
    else if (obj.attachEvent) {
    obj[”e”+type+fn] = fn;
    obj[type+fn] = function() { obj[”e”+type+fn]( window.event ); }
    obj.attachEvent( “on”+type, obj[type+fn] );
    EventCache.add(obj, type, fn);
    }
    else {
    obj[”on”+type] = obj[”e”+type+fn];
    }
    }

    var EventCache = function(){
    var listEvents = [];
    return {
    listEvents : listEvents,
    add : function(node, sEventName, fHandler){
    listEvents.push(arguments);
    },
    flush : function(){
    var i, item;
    for(i = listEvents.length - 1; i >= 0; i = i - 1){
    item = listEvents[i];
    if(item[0].removeEventListener){
    item[0].removeEventListener(item[1], item[2], item[3]);
    };
    if(item[1].substring(0, 2) != “on”){
    item[1] = “on” + item[1];
    };
    if(item[0].detachEvent){
    item[0].detachEvent(item[1], item[2]);
    };
    item[0][item[1]] = null;
    };
    }
    };
    }();
    addEvent(window,’unload’,EventCache.flush);

    function $() {
    var elements = new Array();
    for (var i = 0; i

    Return to “DHTML expand and collapse div menu” article”
    Switch it now

    This is paragraph text that is all up in this place that does some pretty cool stuff
    This is paragraph text that is all up in this place that does some pretty cool stuff
    This is paragraph text that is all up in this place that does some pretty cool stuff
    This is paragraph text that is all up in this place that does some pretty cool stuff

  73. Mike C

    Dang, it appears it converts some of the code to html and chopped the rest. Well, I tried.

  74. John

    Hi:
    Saw you in .net magazine a few weeks back and decide this is what I need for a new site feature I’m creating.

    Being the dumbo I am, I can’t find what I need to write in my HTML, or whether I can then attach the necessary styles via external style sheets.

    So: Ill be having a link on the page which says “Track lists”. When this expands, it will show a div containing all the tracks for a CD.

    I know, I know, boring.

    But your help would be much apreciated. I’ve had torrid time with big business hitting on my website this weekend, and I’m relying on there being good guys out there willing to help.

    All the best. And GREAT site too.

  75. Ryan

    I’m really not understanding how you go about collapsing everything on page load then toggling it open. Mike C I’ve tried your suggestion and what Pat said but it wont work. It would be helpful if there was an example.

  76. John

    Excellant information works as expected and I have put to use on my web site I am developing.

    Hope this point is not out of place here, but I am looking for a calander chooser function that I can use along these lines…, any ideas?

    Thanks.

  77. webshark

    If you wanna make it collapsed as default when your page loads;

    * See the source code from
    http://www.dustindiaz.com/basement/block-toggle.html

    * Find the code in body tag
    * Change it as

    dont forget the grap the css styles from same page also

  78. webshark

    err sorry for no code hope works this time

    find the code div id=myvar
    change it with

    div id=myvar style=display:none

  79. jason

    Thanks…this has been an extremely helpful bit of code. I’ve been looking all day for something like this. And thanks for the helpful discussions on here that made it easy for an amateur like me to employ it.

    My question is…how can this be modified to create a long list of items on a single webpage, whereby each “Switch it now” heading only toggles on and off its specific bit of text? Any help would be really appreciated!

    thanks,
    jason

  80. Tony Noriega

    Dustin, or anyone else….
    Is there a way to make the previous menu close upong clicking the next?
    For instance when you open menu1, then open menu2, menu1 automatically closes…

    thanks all…good stuff

  81. atroz

    brilliant code, thanks so much Dustin.
    And in case anybody missed out on how to close the divs by default, comment 78 did it for me (thanks webshark): just add “style=display:none” to the “div id=myvar” part.

    enjoy!

  82. Tony Noriega

    what about calling the “+” and “-” when you expand and collapse? anyone figure out how to do that?
    thanks

  83. Astoria, NY

    What if the thing you want to collapse is in a itself? I can’t seem to get it to work that way. Any ideas?

  84. Lucas

    First many thanks for writing this helpfull piece of code.

    I have a small request though :)
    Is it possible to automatically change the text “Switch it now” when the text is clicked? Currently it is not changed when clicked.

    Answer much appreciated.

  85. Stephen Hill

    Great stuff, however when using the collapseAll function there is a ‘flicker’ when the page loads, where it loads all of the information on the page then collapses the items. Is there anyway of collapsing them by default and therefore removing the ‘flicker’?

    Cheers for anyone that replies…

  86. Shahul

    How collapse the Div smoothly and slowly.

  87. Travis Watson

    @Stephen Hill
    You can collapse them by default, but if you do so then users who have Javascript disabled will never be able to see your content. If you accept this limitation, then set display: none;.

  88. vinod

    well script and esay to use

    Thanks,

    vinod mahajan
    Web developer
    India

  89. John

    Why bother with all that hard work?
    Where the body tag is just add
    onload=”switchMenu(’myvar’);”
    viola it works

  90. glen

    Very cool.Just now I tested them on firefox2.0 successfully.

  91. vlad

    Hey guys. Maybe i missed something, I want to collapse all the div tags on pageload… I added the ‘collapse all at page load’ text, and changed the div id’s, but none of them collapse??? help!

  92. mark

    ive just been fiddling around trying to hide the text when the page loads, and came up with this:

    just include the code along with ’switchmenu’ function

    
    function hide(){
    document.getElementById("myvar").style.display='none';
    }
    

    and set it to load in the body tag like so:

  93. Erin

    Hi,
    I am sorry to be so naive.. Im trying to complete an assignment, and want to use the collapse/expand coding to tidy things up. However.. every code I come across seems to fail within my existing pages and yet when I use them in a new html document it works fine. Is it possible that the javascript is being interferred by the other js already on my page?
    So far I have not attempted the codes provided here.. as I am unsure how to implement it in the body. Do i just use div tags fot the collapse/expand content and put the subtitle in h1 tags? I apologise again for being so amature. I would appreciate any help anyone could offer me. But if you could really spell it out, thatd be greatly appreciated. Thanks.

  94. n0ah

    And for the last time with postable:

    
    function collapseAll() {
    var objs = Array();
    objs[0] = 'contenttools';
    objs[1] = 'contentstatus';
    objs[2] = 'searchtools';
    objs[3] = 'searchstatus';
    objs[4] = 'dbtools';
    var i;
    for (i=0;i<objs.length;i   ) {
    document.getElementById(objs[i]).style.display = 'none';
    }
    }
    
  95. David Gidwani

    Awesome. Yeah, I had a problem collapsing by default, but the display:none; css worked like a charm.

  96. Sebastian

    Hi, firstly thanks for the wonderful demo, it’s exactly what I’ve been looking for. =) However I’ve one question, is this SEO friendly? I’m not really sure how DHTML works, my guess is that this particular collasping does not affect SEO at all. But just wanting to confirm =)

  97. yoshi kura

    hmm, thanks for this wonderful demo.. i like it. :)

  98. Paintball

    great work, thanks!!

  99. DanielGenser

    Different and Scott:

    Check this out:
    <a href="http://support.internetconnection.net/CODE_LIBRARY/Javascript_Show_Hide.shtml">http://support.internetconnection.net/CODE_LIBRARY/Javascript_Show_Hide.shtml</a>

    I had the same questions you did about automatically collapsing divs when you open another one. The above technique worked for me.

  100. Matt

    Any one had an issue with IE6 with an animated .gif on the page? After the expand the .gif stops. IE 7 and FF 2 are fine. We are considering Flash for this very small animated .gif vs. browser detection. Any ideas?

    By the way the JS code is very cool… I did need to add one tweak… I use a style visibility: hidden to hide the text as the page loads as well as el.style.visibility=”; in the switchMenu function so the text appears. Not sure this would cause the animated .gif to stop.

    Thanks for reading… MPC

  101. iWonder

    Is there any way to I can switch all close/open in one click ? I am not talking about the one on loading of the page.
    If I click a specified image/text/link it should close and open all the ones enabled with this script or that id.

    in other words, if I click “Hide / Open all” then all the divs with id “dustin” whould close i.e

  102. iWonder

    Is there any way to I can switch all close/open in one click ? I am not talking about the one on loading of the page.
    If I click a specified image/text/link it should close and open all the ones enabled with this script or that id.

    in other words, if I click “Hide / Open all” then all the divs with id “dustin” whould close i.e
    <div id="dustin"></div>

  103. trung vtic

    It’s great script .thnk u

  104. Webman

    I’m looking for code that when you click on a link it change to ahover style but if you enter a page the first link should be active.

  105. mokinho

    Where do I call the pageLoad function?

  106. mokinho

    Never mind on the question of “where do I call the pageLoad function? I figured it out. I goes in the body tags!

    Works great now! thanks you for this information. It took me some time to understand, because I’m a slow learner, but I’m persistant;)

    It all makes sense to me now!

  107. Viken

    Hello,

    Even after following all the instructions, I still can’t get the DIV’s to appear collapsed on page load. I’ve read and re-read all the comments and suggestions. I just can’t make it work. Do I have to add an ONLOAD command to my BODY tag?

    In which order must I add the code from the above example windows? 1. Switch Menu 2.Add Event 3.Prototype Dollar 4. Collapse all?

    I really like this code. I’ve gotten it to work fine, but I can’t get the collapse-on-page-load to work.

    Thanks a bunch!

    Viken

  108. mokinho

    Hopefully I can help:}
    This is what I did…

    put the following between your head tags..

    function $() {
    var elements = new Array();
    for (var i = 0; i

    Now in your body tag put the following check your lower case and upper case letters. At first I spelled pageLoad as pageload and it didn’t work. Took me awhile to catch that=0

    In your div tag you will want to assign an ID to which ever one you want to collapse on load of the page.

    example:

    Hide this section

    Now what you will need to do is change the Javascript code collapsAll to reference the div id and you can hide more div tags by calling an id to the div and changing each of the items in the collapseAll to the id of your div tags.


    collapseAll($('hide','myDiv2','myDiv3'));

    I hope this makes sense. It worked for me=)

  109. mokinho

    oopsie my code tags didn’t work.

    put the following in the head tag area…

    function $() {
    var elements = new Array();
    for (var i = 0; i

  110. mokinho

    oopsie my code tags didn’t work. SORRY! Still learning:}

    put the following in the head tag area…

    
    function $() {
    var elements = new Array();
    for (var i = 0; i < arguments.length; i  ) {
    var element = arguments[i];
    if (typeof element == 'string')
    element = document.getElementById(element);
    if (arguments.length == 1)
    return element;
    elements.push(element);
    }
    return elements;
    }
    function collapseAll(objs) {
    var i;
    for (i=0;i<objs.length;i   ) {
    objs[i].style.display = 'none';
    }
    }
    function pageLoad() {
    collapseAll($('myDiv1','myDiv2','myDiv3'));
    }
    addEvent(window,'load',pageLoad);
    

    In the body tag put the following…

    
    onLoad="pageLoad()
    

    In the div tag assign the ID…

    
    div id="hide"
    

    assign the div id to the collapsAll code

    
    collapseAll($('hide','myDiv2','myDiv3'));
    
  111. Snowy

    
    Youre right!!!!
    Its not difficult like everyone makes it out to be.
    Before your code, I had been using a JS Source file which is about
    120 lines long. The JS Source file wasnt capatible with firefox so
    I decided to write my own source file. Didnt think it was this
    simple, thanks.
    
    
  112. RvA

    If you want the cript that shows the reversed version, so that links are collapsed. After clicking, menu will uncollapse.

    Switch menu

    Return to “DHTML expand and collapse div menu” article”
    Switch it now

    This is paragraph text that is all up in this place that does some pretty cool stuff
    This is paragraph text that is all up in this place that does some pretty cool stuff
    This is paragraph text that is all up in this place that does some pretty cool stuff
    This is paragraph text that is all up in this place that does some pretty cool stuff

  113. Big Dummy

    Can ANYONE please display the Example given, but in REVERSE and in plain HTML. I’ve been fiddling around for nearly 2 hours. I’m at my wit’s end! 8-O

  114. boardtc

    works great thanksa lot for posting this, still alive 2 years on! took me a while to implement as I was trying to get it to work using separate css & js files. Also added simple extra to make wrapper look more like a link, here’s that solution

    showhide.css:

    
    <style type="text/css">
    <!--
      .ShowAsLink { color:blue; text-decoration:underline; }
    
      #wrapper {
      }
    
      #showhide {
      }
    -->
    

    showhide.js:

    
    <!--
    function switchMenu(obj) {
    	var el = document.getElementById(obj);
    	if ( el.style.display != "none" ) {
    		el.style.display = 'none';
    	}
    	else {
    		el.style.display = '';
    	}
    }
    //-->
    

    showhide.html (shows code, does not toggle show/hide here):

    
    <html>
    <head>
    	<link href="showhide.css" rel="stylesheet" type="text/css"/>
            <script src="showhide.js" type="text/javascript"></script>
    </head>
    
    <body onload="switchMenu('showhide');">
    <div id="wrapper">
    <h4>What's New</h4>
    <p class="ShowAsLink"><a onclick="switchMenu('showhide');">Last Updated 10 Mar 07</a></p>
    <div id="showhide">
    	<p>This is paragraph text that is all up in this place that does some pretty cool stuff</p>
    </div>
    </div>
    </body>
    </html>
    
  115. confused d

    is there anyway where there is a code for expand and collapse content with text/css and without having to deal with javascript

  116. Big Dummy

    BOARD TC!
    It works GREAT!!! Thanks a bunch!

  117. hiY

    hi is there away to get a cool effect like your collapse bouncing effect …

    im not expereinced in javascript but can you post how to get that effect or a fade in please using this switch menu :)

  118. Alberto

    To be able to toggle with an image just modify the switchMenu function to:

    
    function switchMenu(obj, img) {
    	var el = document.getElementById(obj);
    	if ( el.style.display != "none" ) {
    		el.style.display = 'none';
                    document.getElementById(img).src = "collaps.gif";
    	}
    	else {
    		el.style.display = '';
                    document.getElementById(img).src = "expand.gif";
    	}
    }
    

    Then on the link modify to:

    
    
     toggle
    
    
  119. mike

    i was able to get all of this stuff working, (including the collapse on load event), but i can’t un-collapse the div when clicking it. i’ve tried the code above in the header (using the $ thing), the add event of yours, and also the css display none.. (all seperately) and they all have the same effect - collapsing on load, but no ability to expand. thanks

  120. Kamal

    Very Cool!!.

    This is a very useful effect with less code.

    Thanks ya.

    Keep it up

  121. Nils

    Hi there,

    I am new to web-design and programming but here is my little solution to solve the problem (haveing the toggle-divs closed at page-load and open and therefore visible if javascript is turned off).

    Hope you will like it.

    .html

    
    <p class="toggle" onclick="toggle_visibility('toggle');" title="Show/hide content">Headline</p>
    <div id="toggle" class="toggle">
      <p>FlowText</p>
    </div>
    

    toggle.js

    
    document.write("<link type=\"text/css\" href=\"toggle.css\" media=\"screen\" rel=\"stylesheet\" \/>");
    
    function toggle_visibility(id) {
      var e = document.getElementById(id);
      if(e.style.display == 'block')
        e.style.display = 'none';
      else
        e.style.display = 'block';
      }
    

    toggle.css

    
    .toggle { display: none; }
    
  122. Nils

    Sorry missed something. This has to go to the head-part of the .html as well:
    <script type="text/javascript" src="toggle.js" />

    How does the whole thing work?
    The toggle.js loads the toggle.css (but only if javascript is supported). This toggle.css than applies a style to the FlowText that makes the FlowText invisible at page-load.
    If javascript is turned-off all this does not happen and the Flowtext is visible after page-load (so visitors to the page without js still can see the contentas well).

    Enjoy

  123. Matt

    Actually, I’ve found a way to achieve something similar which enables you to ditch the Javascript altogether. Why would you want to do that?

    JS events aren’t particularly safe - for example if a user creates a web page containing a script tag which is viewed by a site administrator the script can then perform actions on the site which require admin access.

    I’ve got something along the following lines:

    HTML:

    Over over this to reveal dd section
    Stuff you want to hide

    CSS:
    dl.hidestuff dd
    { display:none;
    }
    dl.hidestuff:hover dd
    { display:block;
    }

  124. Matt

    Damn, try this HTML:

    Hover over this to reveal dd section
    Stuff you want to hide

  125. Mohamed

    Thanks a lot for the person who put this code. Its very simple and easy to understand.
  126. Austin

    Fantastic code. Works perfectly… just one query:

    it’s been asked already but has anyone come up with a way of displaying a different image for when the div is open or closed (eg + and -)??

  127. Austin

    just seen the solution further up the page… oops. All works fine.

  128. Kurtovic Emir

    a little modification

    var old=null;

    function switchMenu(obj) {
    if (old!=null){old.style.display=’none’;}
    var el = document.getElementById(obj);
    if ( el.style.display != ‘none’ ) {
    el.style.display = ‘none’;
    }
    else {
    el.style.display = ”;
    }
    old=el;
    }

  129. Chris Pauley

    You need to fix your prototype $() dollar function. It doesn’t work for a single string; it only works for more than one string. Take out this part of your code:

    if (arguments.length == 1)
    return element;

    It serves absolutely no purpose, and actually returns an object instead of an array. I would fix this as soon as possible. It took me quite a while to debug it and find out what was wrong.

  130. sonu

    how to dynamically get the data from the database and put it in the DIV tag.

  131. needlnerdz

    Ooh so many props to you Dustin for coming up with this amazingly easy code to use! I must also send thanks to boardtc for making the instructions to automatically have div’s collapse on load the most obvious and easy to follow. Between the two, you have given my menu great form. thankyouverymuch

  132. Dharam

    ooooohhhh….

    it’s very usefule….

    I will tell you more after i will try it……….

  133. hrefer

    How do you collapse multiple DIV on body onload? Thank you.

  134. Machelle

    How can I make the hidden comment within the same line? Instead of being the next paragraph, like word definitions within a paragraph?

    Also, how do I collapse on page load? Which comment do I follow? I’m brand new to this stuff. I tried the code at the top of the page and a couple within the thread. It keeps saying runtime error. One time it “worked” (showed collapsed) but still had an error. that was when i added the elements display to none, i’ve since started over with the first simple collapse code. How is this so hard?

  135. Greg

    Question.
    I’m new to this, but it’s very cool. I’m just curious as to if theres a way to get it to load out to the right instead of opening to the bottom. And can you make it so when the page loads, they’re all closed, and have to be clicked to open.
    Please let me know as soon as possible.

  136. Eric

    Thanks for sharing the script, Dustin.
    Also, thanks go boardtc for putting up a nice expansion on the idea.

    Best Regards,

    Eric

  137. Reid

    When I made multiple ones and the page opens they are all displayed. If I want them hidden how would I do that?

  138. Reid

    Hide the Div on load by simply adding a style type.

    Add the style=”display:none” to the hidden content div.

    
    
    
  139. Caleb

    The first bit of code is great! In fact, you don’t need the 2nd and 3rd bits of code for elements of your choosing to be collapsed upon page load. Simply write your body tag like this

      

    In that example, MyDiv2 and MyDiv3 are the id’s of the divs that you want to have collapsed when you load the page. That way you can keep the javascript to a minimum and still have divs of your choosing collapsed upon page load.

  140. Charlie

    Why doesn’t this code work when I place the div=’myvar’ around table rows?

  141. Charlie

    OK…got it to work, but the div=’myvar’ has to be around the whole table, not just some TRs. Interesting thing…I’d think it would work either way, but as long as it works now, I’m good.

  142. Laurent

    Hi I can’t use this script with Firefox 2.0. When I click on the link, the content will expand for half a second and collapse.

    Can anyone help me?

    Thanks

  143. Laurent

    The address for the example is

    http://www.inspq.qc.ca/eco/defaultEco.asp?id=4

    Thanks

    Laurent

  144. Ross

    I’ve put in all the code (including the ‘.js’ file), tried and tried, made tweaks…but I still see ‘javascript:;’ at the bottom of the browser when I hover over the links, and nothing happens when I click them except ‘Error On Page’. What am I doing wrong?

  145. Adam

    I can get this to work so on page load the DIV is hidden, you then click the link and it expands/collapses no problem. I would however, love to be able to cater for peopl with JS disabled, so the hidden DIV will show if JS disabled. So far i haven’t been able to achieve it.

  146. Luiz Fukushiro

    if you want to make it collapse all on pageload, just set the “myvar” css to “display:none”. when you click it, it will expand normally

  147. Dale Hay

    Hey!

    Cheers for brilliant code, I have it working fine in Firefox 2. :)

    Here is a low-down of what I’m using and it works. In my <head> tags I have:

    <script type="text/javascript">
    <!--
    function switchMenu(obj) {
    var el = document.getElementById(obj);
    if ( el.style.display != "none" ) {
    el.style.display = 'none';
    }
    else {
    el.style.display = '';
    }
    }

    function hide(){
    document.getElementById("dalehay").style.display='none';
    }
    //-->
    </script>

    Then my BODY tag is like this:
    <body onload="hide();">
    Then my content is like this:
    <a onclick="switchMenu('dalehay');" title="Test">Click Me</a><br><div id="dalehay">Why hello everyone, My name is Dale Hay.</div>

    Try that and hopefully it works for you. Any problems, please contact me via my site.


    Dale
    http://www.dalehay.com

  148. Ben

    Hey there, this is great, just what I’ve been looking for. Can you help me out though if possible please? I want to have several of these on my page forming a long list of them but when I put more than one in, they don’t expand and collapse correctly. When you have two of them for example and click switch now on the bottom one only the top box expands / collapses.

    Is there a way around this and am I being a bit slow on the uptake?

    Thanks.

  149. Daniel

    Hi, has anyone managed to make the cookies work for this script - i’m naff at cookies so i need an example or something - anyone help?
    —–
    Daniel
    CarParkCruisers.Co.Uk

  150. sultan

    HI i m designin a website..i did the above JS for my page having expand/collapse with the +/- image…it works fine except when i expand or collapse the last section, it jumps to the first section….any help….

  151. Internet Marketing Legacy

    Wow. I can’t imagine how it would get easier than that but since this article is from 2005, is there an even easier way now in 2008?

  152. Dylan Lee

    Just chipping in here a couple of years too late. Great solution, I just put it in for an expanding RSS display, many thanks to those involved. Just thought I’d mention that instead of using javascript to hide everything once the page loads (my pages are bloated… so you could see everything before it became hidden by the onload event) I just set the style on the relevant divs to hide:

    seems to be quite tidy and a lot faster in my situation.

  153. Juhi

    Do these paragraphs have to be inside ‘div’ tags? Is there any way to get the same effect using ” tags instead?
    I am using WordPress for my blog and their stupid WYSIWYG editor automatically turns all the ‘div’s into ‘p’s !

  154. BL

    Hi, Dustin and others!

    When someone asks you a question, just why is it for you so hard to answer it directly to the point and do, what’s asked of you?

    Several people have asked, how to make that expand-collapse code appear closed the first time (upon loading the page). Dustin, you even defended yourself, when someone questioned the usefulness of your http://www.dustindiaz.com/basement/block-toggle.html, by the excuse that other people have found it useful. No, that guy was right, because your use in the demo is the unlikely one, while most people would like to see it appear collapsed, when the page loads. So you made a demo for the least used version, but you just can’t admit it.

    Now even if you did, then people asked you and each other, how to make it appear collapsed upon loading. But all of you just confused the askers unnecessarily, because you never put up the full code from html tag to html tag. So you got misunderstood, of course and you made your askers waste their times. And why? Just because you were too LAZY (yes, lazy, I said it, now start complaining about me flaming you, because you just can’t absorb the truth) to write out the whole code the first time!

    There was a guy, who put up a very simple answer, namely to change the DIV id=myvar to DIV id=myvar style=display:none, but even he did not write out the whole code, but this at least worked.

    So Dustin, you have upload access to your page, so it’s your job to put up a demo example of this, so do it! Don’t talk, no excuses, just do it! And yes, it’s gonna be exactly the same page from html to html, except that little difference and I know, you want to say, why so much work, people can figure it out, it’s common sense and bla-bla-bla. You know, what’s common sense? That you put it up in a COMPLETE version and stop doing HALF A JOB and giving people snippets of answers. Get down from your high horse and realize that not everyone is a pro, many are even total beginners in JavaScript, so you have to consider the people with the least knowledge first!

    And why all this work, if it’s almost the same thing twice? I’ll tell you, if you can’t think of it yourself, because you’re preoccupied with how to avoid writing down something properly. It’s the DEMO that counts, so we can see in actuality that it really works and not just that you’re saying, it works. A DEMO speaks for itself. How often have people encountered the situation, where the guru’s (in this case Dustin’s) description weren’t worth a dime, but when they saw the DEMO and dissected it, everything became clear? I’m 100% sure that I’m not the only one, who experienced this! I’m so sure!!!

    So Dustin, right next to that link to your block-toggle.html DEMO, put up another link to the DEMO, where the whole thing comes up as collapsed first (on load)! No need to write scientific dissertations on seven ways to toggle, etc. That’s an overkill, if you haven’t solved your basic problem first!

    Well, your basic problem is logic. So BEFORE you go on to more complicated scenarios derived from the original code, first fix your original code’s logic. So let me tell you again: that guy, who criticized you regarding usefulness, was right, because 99% (if not 100%) of the time people expect it to appear collapsed and the user is the one, who should be left the free choice to open, if he’s interested or leave it unopened, if he’s not interested in that link!

    As proof to that just see a movie page on YouTube.com or do a from-to directions search on MapQuest.com! Yahoo Maps, Google Maps, etc. are all the same way: COLLAPSED BY DEFAULT. So do I need to say more? All of these websites speak for me! So just accept it that you are a 100% wrong, as far as USABILITY is concerned, so put up THAT version as a DEMO, where the link appears as collapsed first! This is the ONLY LOGICAL way that people expect! If you don’t get this, you simply have NO LOGIC, period!

    Save the ‘Oh, you flamed me’ crybaby stuff! Just see your mistake and change! All of you, who just give snippets of code as answers instead of the WHOLE thing or a DEMO! Learn to do things PROPERLY, not in a messy way, otherwise go home and don’t put up a website or a comment on the Internet, because then you’re good for nothing!

    PROPERNESS, COMPLETENESS, LOGIC and DEMOS!!! Lazy people out!!! Thank you!

  155. Luise

    I’m looking for a nice guy to tell me how I can change this script to (in a list) only show one expanded item at a time. I mean, if you expand one, it automatically collapses all the others.

    Thanks, this is driving me crazy…

  156. BW

    Jeez. I don’t even have time or the interest to read all that B.S. above.

    Back to the using an image that changes depending on the state. Alberto said on March 15, 2007, that to be able to toggle with an image just modify the switchMenu function (and he then provides modified code). But then he says, “Then on the link modify to: toggle”

    Now, what the heck does that mean? Anyone?

Leave a Reply

Phone Number:

If you're about to post code in your comment, please wrap your code with the tag-combo <pre><code>. Also please escape your html entities - otherwise they will be stripped out. I recommend using postable.

Get "JavaScript Design Patterns"

"As a web developer, you'll already know that JavaScript™ is a powerful language, allowing you to add an impressive array of dynamic functionality to otherwise static web sites. But there is more power waiting to be unlocked--JavaScript is capable of full object-oriented capabilities, and by applying OOP principles, best practices, and design patterns to your code, you can make it more powerful, more efficient, and easier to work with alone or as part of a team."

Buy JS Design Patterns from Amazon.com Buy JS Design Patterns from Apress

Flickr

Submit a Prototype

All content copyright © 2003 - 2007 under the Creative Commons License. Wanna know something? Just ask.

About | Archives | Blog Search

[x] close

Loading...

Submit a prototype

By checking this prototype I agree that I am not submitting false credentials, pornography, or a hate crime website. I also understand that by submitting my entry I may or may not be accepted, and if accepted, my entry may be taken down at any given time if I violate these terms.