How to getElementByClass instead of GetElementById with JavaScript?

Alan picture Alan · Dec 19, 2009 · Viewed 404.9k times · Source

I'm trying to toggle the visibility of certain DIV elements on a website depending on the class of each DIV. I'm using a basic JavaScript snippet to toggle them. The problem is that the script only uses getElementById, as getElementByClass is not supported in JavaScript. And unfortunately I do have to use class and not id to name the DIVs because the DIV names are dynamically generated by my XSLT stylesheet using certain category names.

I know that certain browsers now support getElementByClass, but since Internet Explorer doesn't I don't want to go that route.

I've found scripts using functions to get elements by class (such as #8 on this page: http://www.dustindiaz.com/top-ten-javascript/), but I can't figure out how to integrate them with with my toggle script.

Here's the HTML code. The DIVs themselves are missing since they are generated on page load with XML/XSLT.

Main Question: How do I get the below Toggle script to get Element by Class instead of get Element by ID?

<html>

<head>

<!--This is the TOGGLE script-->
<script type="text/javascript">
<!--
    function toggle_visibility(id) {
       var e = document.getElementById(id);
       if(e.style.display == 'block')
          e.style.display = 'none';
       else
          e.style.display = 'block';
    }
//-->
</script>

</head>

<!--the XML/XSLT page contents will be loaded here, with DIVs named by Class separating dozens of li's-->

<a href="#" onclick="toggle_visibility('class1');">Click here to toggle visibility of class 1 objects</a>

<a href="#" onclick="toggle_visibility('class2');">Click here to toggle visibility of class 2 objects</a>

</body>
</html>

Answer

Christian C. Salvad&#243; picture Christian C. Salvadó · Dec 19, 2009

The getElementsByClassName method is now natively supported by the most recent versions of Firefox, Safari, Chrome, IE and Opera, you could make a function to check if a native implementation is available, otherwise use the Dustin Diaz method:

function getElementsByClassName(node,classname) {
  if (node.getElementsByClassName) { // use native implementation if available
    return node.getElementsByClassName(classname);
  } else {
    return (function getElementsByClass(searchClass,node) {
        if ( node == null )
          node = document;
        var classElements = [],
            els = node.getElementsByTagName("*"),
            elsLen = els.length,
            pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)"), i, j;

        for (i = 0, j = 0; i < elsLen; i++) {
          if ( pattern.test(els[i].className) ) {
              classElements[j] = els[i];
              j++;
          }
        }
        return classElements;
    })(classname, node);
  }
}

Usage:

function toggle_visibility(className) {
   var elements = getElementsByClassName(document, className),
       n = elements.length;
   for (var i = 0; i < n; i++) {
     var e = elements[i];

     if(e.style.display == 'block') {
       e.style.display = 'none';
     } else {
       e.style.display = 'block';
     }
  }
}