Wednesday, March 11, 2009

Pure Accessible JavaScript Tabs

Found some code I did a while ago (pre jQuery) of a simple tabbed navigation implementation using JavaScript and basic CSS. Posting if anyone is interested.

HTML

<ul id="tabnav">
 <li><a href="#tab1">Tab 1</a></li>
 <li><a href="#tab2">Tab 2</a></li>
 <li><a href="#tab3">Tab 3</a></li>
</ul>
<div id="tabs">
 <div id="tab1"><a name="tab1"></a>
  <h1>Tab 1</h1>
  This is the contents of Tab 1
 </div>
 <div id="tab2"><a name="tab2"></a>
  <h1>Tab 2</h1>
  This is the contents of Tab 2
 </div>
 <div id="tab3"><a name="tab3"></a>
  <h1>Tab 3</h1>
  This is the contents of Tab 3
 </div>
</div>

CSS

#tabnav {
 width: 100%;
 overflow: hidden;
 list-style-type: none;
 margin: 0;
 padding: 0;
}
#tabnav li {
 float: left;
 padding: 6px;
 margin: 0;
}
#tabnav li.activetab {
 font-weight: bold;
}

JavaScript (hopefully the inline comments should explain how it works). Add in script tag after HTML

// setup tabs, default is 'tab2'
setupTabs("tab2");
 
function setupTabs(tabDefault) {
 if (document.getElementById) {
  // get tab navigator
  var tabnav = document.getElementById('tabnav');
  if(tabnav) {
   // get list items in tab navigator
   var tablist = tabnav.getElementsByTagName('li');
   // loop through list items
   for (i=0;i<tablist.length;i++) {
    // get tab links (i.e. anchor tags)
    var tablinks = tablist[i].getElementsByTagName('a');
    // loop through tab links
    for (j=0;j<tablinks.length;j++) {
     // get hash for current tablink (i.e. the #tabname portion)
     var hash = tablinks[j].hash;
     // set onclick attribute to toggle the tabs (does not work in IE)
     tablinks[j].setAttribute("onclick","toggleTabs('"+hash.substring(1)+"'); return false;");
     // detect IE (other browsers don't support attachEvent)
     if (tablinks[j].attachEvent) {
      // set onclick to toggle tabs
      tablinks[j].onclick = Function("toggleTabs('"+hash.substring(1)+"'); return false;");
     }
     // if has is default tab
     if (hash == ("#" + tabDefault)) {
      // set parent nodes css class to 'activetab' (i.e. 'li' tag) and show tab
      tablinks[j].parentNode.className = "activetab";
      showTab(tabDefault);
     } else {
      // set parent nodes css class to empty (i.e. 'li' tag) and hide tab
      tablinks[j].parentNode.className = ""
      hideTab(hash.substring(1));
     }
    }
   }
  }
 }
}
function showTab(tabId) {
 if (document.getElementById) {
  // get current tab
  var currentTab = document.getElementById(tabId);
  // show tab by setting display style to blank string
  currentTab.style.display = "";
  // get anchor tags in current tab
  var currentTabAnchors = currentTab.getElementsByTagName('a'); 
  // loop through anchor tags
  for (k=0;k<currentTabAnchors.length;k++) {
   // if anchor tag has same name as current tag id, hide it
   if(currentTabAnchors[k].name==tabId) {
    currentTabAnchors[k].style.display = "none";
   }
  }
 }
}
function hideTab(tabId) {
 if (document.getElementById) {
  document.getElementById(tabId).style.display = "none";
 }
}
function toggleTabs(tabId) {
 if (document.getElementById) {
  // an array of all the sections
  var sectionnames = new Array();
  // get tab navigator
  var tabnav = document.getElementById('tabnav');
  // get list items in tab navigator
  var tablist = tabnav.getElementsByTagName('li');
  // loop through list items
  for (i=0;i<tablist.length;i++) {
   // get tab links (i.e. anchor tags)
   var tablinks = tablist[i].getElementsByTagName('a');
   // loop through tab links
   for (j=0;j<tablinks.length;j++) {
    // get hash for current tablink (i.e. the #tabname portion)
    var hash = tablinks[j].hash;
    // add has to sections array
    sectionnames.push(hash.substr(1));
    // if hash is selected tab
    if (hash == ("#" + tabId)) {
     // set parent nodes css class to 'activetab' (i.e. 'li' tag)
     tablinks[j].parentNode.className = "activetab";
    } else {
     // set parent nodes css class to empty (i.e. 'li' tag)
     tablinks[j].parentNode.className = ""
    }
   }
  }
  // get tabs
  var tabs = document.getElementById('tabs');
  // get tab sections
  var sections = tabs.childNodes;
  // loop through sections
  for (i=0;i<sections.length;i++) {
   // if node is not a div, then continue to next loop item
   if (sections[i].nodeName!='DIV') continue;
   // if current section id matches tabId show it
   if(sections[i].id==tabId) {
    showTab(sections[i].id);
   } else {
    // get child anchor nodes
    var atags = sections[i].getElementsByTagName("a");
    // if anchor nodes have been found
    if (atags.length > 0) {
     // loop through the section names
     for (j=0;j<sectionnames.length;j++) {
      // if first anchor tags name matches the current section id, hide the tab
      if(sectionnames[j] == atags[0].getAttribute("name")) {
       hideTab(sections[i].id);
      }
     }
    }
    
   }
  }
 }
 return false;
}

No comments: