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
tdortrhas aclassdefined.
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; }

Some time ago, I read an article about Zebra tables with javascript. This methods saves a lot of unnecessary markup, but has some flaws:
tdortrhas aclassdefined.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; }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.
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) {
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; }
CSS3 will be really nice, but we have to wait for it