Zebra tables revisited

Posted by Jorge Bernal February 13, 2006

Some time ago, I read an article about Zebra tables with javascript. This methods saves a lot of unnecessary markup, but has some flaws:

  • You can only invoke it for a specific table
  • It doesn’t work if the td or tr has a class defined.

So I have rewritten this library to match all the tables with the same class (eg. listing).

function stripe(cls) {

   // the flag we'll use to keep track of
   // whether the current row is odd or even
   var even = false;

   // obtain a reference to the desired table
   // if no such table exists, abort
   var tables = document.getElementsByTagName("table");
   for (var t = 0; t < tables.length; t++) {
     if (tables[t].className == cls) {
       // by definition, tables can have more than one tbody
       // element, so we'll have to get the list of child
       // tbody's
       var tbodies = tables[t].getElementsByTagName("tbody");

       // and iterate through them...
       for (var h = 0; h < tbodies.length; h++) {

        // find all the tr elements...
         var trs = tbodies[h].getElementsByTagName("tr");

         // ... and iterate through them
         for (var i = 0; i < trs.length; i++) {

           trs[i].className =
             even ? 'tr_even' : 'tr_odd';
           // flip from odd to even, or vice-versa
           even =  ! even;
         }
       }
     }
   }
 }

Then you can define your row styles like:

tr.tr_even { background-color: #ffffff; }
tr.tr_odd { background-color: #ecddac; }

Share and Enjoy:
  • Digg
  • del.icio.us
  • Facebook
  • Furl
  • Google Bookmarks
  • email
  • StumbleUpon

Most Commented Posts

1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...

5 Responses to “Zebra tables revisited”

  1. koke says:

    Some time ago, I read an article about Zebra tables with javascript. This methods saves a lot of unnecessary markup, but has some flaws:

    • You can only invoke it for a specific table
    • It doesn’t work if the td or tr has a class defined.

    So I have rewritten this library to match all the tables with the same class (eg. listing).

    function stripe(cls) {
    
       // the flag we'll use to keep track of
       // whether the current row is odd or even
       var even = false;
    
       // obtain a reference to the desired table
       // if no such table exists, abort
       var tables = document.getElementsByTagName("table");
       for (var t = 0; t < tables.length; t++) {
         if (tables[t].className == cls) {
           // by definition, tables can have more than one tbody
           // element, so we'll have to get the list of child
           // tbody's
           var tbodies = tables[t].getElementsByTagName("tbody");
    
           // and iterate through them...
           for (var h = 0; h < tbodies.length; h++) {
    
            // find all the tr elements...
             var trs = tbodies[h].getElementsByTagName("tr");
    
             // ... and iterate through them
             for (var i = 0; i < trs.length; i++) {
    
               trs[i].className =
                 even ? 'tr_even' : 'tr_odd';
               // flip from odd to even, or vice-versa
               even =  ! even;
             }
           }
         }
       }
     }

    Then you can define your row styles like:

    tr.tr_even { background-color: #ffffff; }
    tr.tr_odd { background-color: #ecddac; }
    

  2. mat says:

    FWIW, instead of getElementsByTagName(“tbody”), getElementsByTagName(“tr”), and getElementsByTagName(“td”), you can use .tBodies[], .rows[], .cells[]. These are standard DOM HTML methods, and are much more efficient.
    See http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-64060425 for more info.

  3. Dean says:

    Thanks for this Koke, I read the original article but didn’t like the code so this is quite useful.

    One flaw I experienced was that if you have multiple classes assigned to the table it stopped working. Below is the code to fix this,

    I’m using hard coded class names for striping, so remember to switch those out for cls, but it should still work.

    Replacing

    if (tables[t].className == stripe) {

    with
    if ((‘ ‘+tables[t].className+’ ‘).indexOf(“stripe”) != -1) {

  4. J.B. Nicholson-Owens says:

    Thanks for sharing that code. This will be so much easier when CSS3 selectors are more popular and when people gain the guts to walk away from letting Microsoft dictate what we can do on the web by caving into its proprietary always-behind web browser.

    From the draft of CSS3 selectors, the odd rows of the table:
    tr:nth-child(2n+1);
    tr:nth-child(odd);

    and the even rows:
    tr:nth-child(2n);
    tr:nth-child(even);

    So, the equivalent using CSS3:
    tr:nth-child(even) { background-color: #ffffff; }
    tr:nth-child(odd) { background-color: #ecddac; }

  5. koke says:

    CSS3 will be really nice, but we have to wait for it :(

Leave a Reply