A JavaScript Accordion to Show and Hide HTML

  You are currently not logged in. You can view the forums, but cannot post messages. Log In | Register

19-Jan-09 00:00
This is a forum topic for discussing the article "A JavaScript Accordion to Show and Hide HTML":

http://www.elated.com/articles/javascript-accordion/

Build a JavaScript accordion script that lets visitors show and hide parts of an HTML Web page.
02-Mar-10 19:07
Hi, thanks for the tutorial. Is there any way to have the 2nd or 3rd accordion item open as the default, instead of the 1st?

--
Robin
05-Mar-10 15:02
Hi Robin, welcome to Elated.

Just change the following code within the init() function:


// Hide all accordion item bodies except the first
for ( var i = 1; i < accordionItems.length; i++ ) {
accordionItems[i].className = 'accordionItem hide';
}


to:


// Hide all accordion item bodies except one
for ( var i = 0; i < accordionItems.length; i++ ) {
if ( i != 2 ) accordionItems[i].className = 'accordionItem hide';
}


Change the "2" to the item you want to show (0=first item, 1=second item, 2=third item and so on).

Hope that helps!
Matt

--
Matt Doyle, Elated
05-Mar-10 21:56
That works great. Thank you!

--
Robin
09-Mar-10 02:57
You're welcome. Feel free to ask if you need any more help.

Cheers,
Matt

--
Matt Doyle, Elated
28-Sep-10 14:40
Hi Matt,

Thank you for all of the above information. I'm wondering if there is a way to keep the accordion opened if/when you add a link to another page(without opening the new page in another window) and you navigate back to the accordion page.

Thanks,
Debbie

--
Debbie
29-Sep-10 18:59
@dsulek: You mean using the browsers' Back button? Tricky - you'd need to store the currently-selected item's hash value in the URL so that it's recorded in the browser history. Then when the Back button is pressed, the browser will remember the history and load the URL with the hash. Your JavaScript would then need to read this hash value and restore the selected div.

Here's something similar that I wrote for my JavaScript Tabs tutorial (which works in a similar way to the accordion):

http://www.elated.com/forums/topic/4717/#post18005

You'll also need to modify toggleItem() to set the hash in the address bar accordingly, eg:


document.location.hash = (the hash value);


--
Matt Doyle, Elated
08-Oct-10 14:50
Very grateful to have this code and instructions, Matt. Thank you.

Please would you show me how and where to add a millisecond timer to the code to give a slower reveal?

Thanks again.
10-Oct-10 21:13
Hi sansarin, welcome to Elated!

Easiest way is to hack a bit of jQuery in there. Use jQuery's slideUp() and slideDown() methods to show/hide the items. Full example:


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<!-- This page is copyright Elated Communications Ltd. (www.elated.com) -->

<title>JavaScript accordion example</title>

<style type="text/css">
body { font-size: 80%; font-family: 'Lucida Grande', Verdana, Arial, Sans-Serif; }
.accordionItem h2 { margin: 0; font-size: 1.1em; padding: 0.4em; color: #fff; background-color: #944; border-bottom: 1px solid #66d; }
.accordionItem h2:hover { cursor: pointer; }
.accordionItem div { margin: 0; padding: 1em 0.4em; background-color: #eef; border-bottom: 1px solid #66d; }
.accordionItem.hide h2 { color: #000; background-color: #88f; }
</style>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>

<script type="text/javascript">
//<![CDATA[

var accordionItems = new Array();

function init() {

// Grab the accordion items from the page
var divs = document.getElementsByTagName( 'div' );
for ( var i = 0; i < divs.length; i++ ) {
if ( divs[i].className == 'accordionItem' ) accordionItems.push( divs[i] );
}

// Assign onclick events to the accordion item headings
for ( var i = 0; i < accordionItems.length; i++ ) {
var h2 = getFirstChildWithTagName( accordionItems[i], 'H2' );
h2.onclick = toggleItem;
}

// Hide all accordion item bodies except the first
for ( var i = 1; i < accordionItems.length; i++ ) {
accordionItems[i].className = 'accordionItem hide';
$(accordionItems[i]).find('div').slideUp();
}
}

function toggleItem() {
var itemClass = this.parentNode.className;

// Hide all items
for ( var i = 0; i < accordionItems.length; i++ ) {
accordionItems[i].className = 'accordionItem hide';
$(accordionItems[i]).find('div').slideUp();
}

// Show this item if it was previously hidden
if ( itemClass == 'accordionItem hide' ) {
this.parentNode.className = 'accordionItem';
$(this).parent().find('div').slideDown();
}
}

function getFirstChildWithTagName( element, tagName ) {
for ( var i = 0; i < element.childNodes.length; i++ ) {
if ( element.childNodes[i].nodeName == tagName ) return element.childNodes[i];
}
}

//]]>
</script>
</head>
<body onload="init()">
<h1>JavaScript accordion example</h1>

<div class="accordionItem">
<h2>About accordions</h2>

<div>
<p>JavaScript accordions let you squeeze a lot of content into a small space in a Web page.</p>
<p>This simple accordion degrades gracefully in browsers that don't support JavaScript or CSS.</p>
</div>
</div>

<div class="accordionItem">
<h2>Accordion items</h2>

<div>
<p>A JavaScript accordion is made up of a number of expandable/collapsible items. Only one item is ever shown at a time.</p>
<p>You can include any content you want inside an accordion item. Here's a bullet list:</p>
<ul>
<li>List item #1</li>
<li>List item #2</li>
<li>List item #3</li>

</ul>
</div>
</div>

<div class="accordionItem">
<h2>How to use a JavaScript accordion</h2>
<div>
<p>Click an accordion item's heading to expand it. To collapse the item, click it again, or click another item heading.</p>

</div>
</div>

<p><a href="/articles/javascript-accordion/">Return to the JavaScript Accordion article</a></p>

</body>
</html>


More on jQuery animations at:

http://www.elated.com/articles/super-easy-animated-effects-with-jquery/

Cheers,
Matt

--
Matt Doyle, Elated
11-Oct-10 17:41
Firstly, thank you for posting this. I was just dusting off an old Javascript collapse code, and this looks way more elegant than the code I was using.

I want to use an image/button to show and hide the content, so I would just replace the "H2" with "img" in this bit of code I'm assuming correct?


// Assign onclick events to the accordion item category image
for ( var i = 0; i < accordionItems.length; i++ ) {
var img = getFirstChildWithTagName( accordionItems[i], 'img' );
img.onclick = toggleItem;
}


And then if I want all accordianItem content to hide itself by default, I would just remove this portion of the javascript right?


// Hide all accordion item bodies except the first
for ( var i = 1; i < accordionItems.length; i++ ) {
accordionItems[i].className = 'accordionItem hide';
}


I'm sure I'll figure this out through trial and error, but confirmation is always nice =)

Thanks again

[Edited by myexpression on 11-Oct-10 16:46]
12-Oct-10 04:46
@myexpression:

"I want to use an image/button to show and hide the content, so I would just replace the "H2" with "img" in this bit of code I'm assuming correct?"

Probably "IMG", but yes. But why not just style the H2 using a CSS background image? Semantically better, and you won't have to change the JavaScript.

"And then if I want all accordianItem content to hide itself by default, I would just remove this portion of the javascript right?"

If you mean you want to hide the first item too on page load, then change the 1 to a 0:


// Hide all accordion item bodies
for ( var i = 0; i < accordionItems.length; i++ ) {
accordionItems[i].className = 'accordionItem hide';
}


Cheers,
Matt

--
Matt Doyle, Elated
14-Oct-10 09:46
Hi, this is a great work and is really easy to understand, but i want a little help... i want to know if is any way to mantain multiple tabs opened, thanks man.
14-Oct-10 22:15
@JUNTAI: Not quite sure how that would work...?

--
Matt Doyle, Elated
15-Oct-10 13:37
Thank you, I did manage to find a solution to mantain multiple accordion items opened, it's really easy...

just replace this code on the function toggleItem():



function toggleItem() {
var itemClass = this.parentNode.className;
// Hide all items
for ( var i = 0; i < accordionItems.length; i++ ) {
if ( accordionItems[i].className == 'accordionItem hide' ) accordionItems[i].className = 'accordionItem hide';
//if ( accordionItems[i].className == 'accordionItem' ) accordionItems[i].className = 'accordionItem hide';
}
// Show this item if it was previously hidden
//if ( itemClass == 'accordionItem hide' || itemClass == 'accordionItem') {
this.parentNode.className = 'accordionItem';
if ( itemClass == 'accordionItem') {
this.parentNode.className = 'accordionItem hide';
}
//}
}



Thanks again man, this script is awesome...
17-Oct-10 22:06
@JUNTAI: Ah, I see what you mean now. Nice hack!

--
Matt Doyle, Elated
16-Nov-10 16:11
Instead of leaving it with inline CSS and inline JS, I copied and pasted the HTML, JS and CSS in to separate files. Now the example doesn't expand/collapse at all.

I removed the

<BODY onload=init()>

from the HTML page and added

window.onload = init;

to the JS file instead.

Do you know why the example doesn't work when I separate the HTML, JS and CSS?
16-Nov-10 22:38
@adidasdude: Hard to tell without seeing the actual page. Do you get any errors in the error console? What browser are you using?

You could try putting the call to init() in the markup after the accordion markup perhaps:


<script>
init();
</script>


--
Matt Doyle, Elated
16-Nov-10 23:15
Everything shows up fine and my cursor changes to a click icon when I hover over the accordion. However, I can't click on anything.

Due to restrictions, I have to use IE7. I installed a web developer plugin for IE7 but it's not as good as firebug or safari's web developer stuff. Do you know how to check the error console on IE7?

I will try your code first thing tomorrow and I'll try to paste what the error console says.

Thanks again.
18-Nov-10 03:53
Tricky with IE7- you could try this: http://bytes.com/topic/javascript/answers/677272-finding-javascript-errors-ie-7-a

On IE8, just hit F12...

--
Matt Doyle, Elated
25-Aug-11 14:00
Hello,

Is there a way to get this script to work without using getElementsByTagName but using getElementByID?

Thanks!
29-Aug-11 07:53
@cklein: Why would you want to?

--
Matt Doyle, Elated
17-Dec-11 15:26
I am writing a website with an FAQ page that displays with all the answers hidden using much of your code approach above (works fine). What I'd like to be able to do is to sometimes link to the FAQ page from other pages within the website and instead display the answer to one specific question when I come from that particular link.

For example, the 5th FAQ may be "What is an XXX" and another page may have "and when you use an XXX" I want to be able to have a link from XXX to the FAQ page and automatically show the answer to question 5 ("what is an XXX").

I hope that makes sense.
17-Dec-11 17:07
@ MarkH

Are you referring to dynamically loading in that particular div's contents through AJAX?

Can you please send a screenshot?
17-Dec-11 19:32
No, nothing that fancy. I simply mean going to the FAQ page but instead of by default, hiding all the answers (eg, if you selected FAQ page from the mainmenu only a list of questions show), un-hiding/showing the answer to the relevant question that the link refers to. In my example above, this would be the answer to question 5.
19-Dec-11 23:25
@MarkH: I posted some code for my JavaScript Tabs script that I think will do what you need:

http://www.elated.com/forums/topic/4717/#post18005

The accordion code is fairly similar to the tabs code, so it should be simple to integrate.

--
Matt Doyle, Elated
29-Aug-13 12:40
Hi. Thanks for the post. I want ot ask how I would apply this when I don't have access to the <body> tag? I am working inside of a CMS where I'm only accessing the content area.

Thanks for the reply
29-Aug-13 15:51
Then call the init() method after the content and before the closing body tag.

--
Chris.
So long, and thanks for all the fish.
http://webmaster-talk.eu/
09-Nov-13 05:40
Thank you for showing us how to create a nice lean accordion with great flexibility.

But here is my big problem, and it is not with the technical side of the code, but legal usage.

A while ago I searched high and low for a lean accordion to use in an html app. I also looked at licensing, and narrowed it down to just a couple of accordions, this being the preferred. I'm not sure if I got the licencing into a muddle (I just verified that the other one is free to use under CC), but I believed this one to be MIT licensed, as that is what I added to the attribution. Now I can't find any reference to it on this site, only the general Terms of Use which make "content" copyright, permission required.

Can you please clarify what the usage terms are of the accordion, as well as the tabs and similar?

And will I go to jail now 8-O ?

Many appologies if I made a mistake, and I will rectify if I have made one.

 
New posts
Old posts

Follow Elated