Tuesday, May 11, 2010

A JavaScript Accordion to Show and Hide HTML

Build a JavaScript accordion script that lets visitors show and hide parts of an HTML Web page.

javascript-accordion-shot

As you can see, a JavaScript accordion is a useful way to squeeze lots of page content into a small space. It consists of a list of items, of which only one is expanded at any one time. When you click on another item's heading, the first item collapses and the second item expands.

Let's see how the accordion is put together.

Creating the HTML

The first thing to do is build the markup. It's nice to keep the HTML as simple as possible, so we'll just use a div element with a class of accordionItem for each accordion item. Within eachaccordionItem div we'll place two elements: an h2 element for the item's title bar, and a divelement for the item's content. Here's the first of the three accordion items as an example:

<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>



(To add more accordion items, just create additional accordionItem divs in a similar fashion.)



Creating the CSS



The CSS in the page serves two purposes:





  1. It makes the accordion look pretty and more usable.




  2. It provides a .hide CSS class for hiding accordion item bodies.




Here's the CSS used in the example:




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; }




.accordionItem.hide div { display: none; }



Each CSS rule does the following:



body  :This just sets a nice font and font size for the page.


.accordionItem h2  :Styles the item heading inside each accordion item.


.accordionItem h2:hover  :Makes the mouse cursor change to a pointer when the heading is hovered over. (Doesn't work in IE6 — no biggie.)


.accordionItem div :Styles the content div inside each accordion item.


.accordionItem.hide h2  :Styles the item headings for all the collapsed items.


.accordionItem.hide div   :Ensures that the bodies of the collapsed items are not shown.



Creating the JavaScript



Now comes the fun part! The basic strategy here is:





  • Start by assigning a toggleItem() onclick event handler to each of the h2 accordion item headings.




  • Hide all item bodies except the first, so that only the top item is visible when the page loads.




  • When an item heading is clicked, toggleItem() hides all items in the list, then shows the clicked item if previously hidden. This allows the visitor to toggle any item while keeping the other items collapsed.




INFO



Why not hide all items except the first by using markup, rather than JavaScript? Because:





  • It would require extra markup.




  • On non-JavaScript browsers the hidden items would be permanently hidden, rendering them unreadable.




First you need to create a global array to hold the accordionItem divs:




  var accordionItems = new Array();



Now you need to create three functions:





  • init() to set up the accordion




  • toggleItem() to expand/collapse an accordion item




  • getFirstChildWithTagName(), a short helper function used by init().




These functions are described below.




The init() function



The init() function is triggered by the body element's onload event:




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';




      }




    }



This function comprises 3 parts, as follows:





  1. The first part pulls the accordion item divs into JavaScript DOM objects and stores the objects in the accordionItems array. To do this it first callsdocument.getElementsByTagName() to get a list of all divs in the page. Then it loops through this list, pushing any divs that have a class of 'accordionItem' onto the accordionItemsarray.




INFO



Find out about getElementsByTagName() in Retrieving page elements via the DOM. Theinit() function also accesses the element.className property, which is a handy shorthand way of setting or getting an element's class attribute.



2.The second block of code goes through each accordion item div, assigning an onclickevent handler function called toggleItem() to the h2 element inside the div. To locate the h2element it calls a helper function, getFirstChildWithTagName() (described in a moment).



3.The third chunk of code loops through all the accordion items except the first, setting eachdiv's class to 'accordionItem hide'. Due to the CSS in the page, this has the effect of hiding each item's content div, as well as giving each item's h2 heading an "unselected" style.



Register the init() function as the body element's onload event handler, like this:



<body onload="init()">


This causes init() to run when the page loads.



The toggleItem() function


 



The toggleItem() event handler is called when an accordion item's heading is clicked on. It deals with the showing and hiding of the accordion items:



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


The function:




  1. Stores the current CSS class of the accordion item whose heading was clicked in anitemClass string variable to refer to later.


  2. Loops through all the accordion items, hiding them by setting their class to 'accordionItem hide'.


  3. Shows the clicked item if its previous class was 'accordionItem hide' — that is, if it was previously hidden. This provides the toggling mechanism. To show the item it simply sets its CSS class to 'accordionItem' instead of 'accordionItem hide'.



INFO



Notice that, in an event handler function, this refers to the object that triggered the event (in this case the item heading that was clicked on).



The getFirstChildWithTagName() function


 



Nearly finished! You just need to create a small helper function, getFirstChildWithTagName(), that retrieves the first child of a specified element that matches a specified tag name. This function is used by init() to retrieve the first h2 element inside each accordionItem divelement.



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


The function is very simple. It loops through each of the child nodes of the supplied element until it finds a node with the supplied tag name. When it finds such a node, it returns it.



INFO



Find out about the childNodes and nodeName properties in Looking inside DOM page elements.



Putting it all together



That's all there is to building a JavaScript accordion! Take a look at the demo again, and view the page source to see how the HTML, CSS and JavaScript come together to make the accordion.



SOURCE elated


People who read this post also read :



If you liked my post then,

Subscribe to this site via Email:

Click here to Subscribe to FREE email updates from "itrickz", so that you do not miss out anything that can be valuable to you and your blog!!

DropJack!
Digg Google Bookmarks reddit Mixx StumbleUpon Technorati Yahoo! Buzz DesignFloat Delicious BlinkList Furl

0 comments: on "A JavaScript Accordion to Show and Hide HTML"

Post a Comment