Color Alternate Rows

With CSS and modern browsers, it is easy to shade the colors of alternating rows.
For example:


tr:nth-child(odd) {background-color:#ffd;}

IE8 does not understand nth-child, so we assign classnames to alternate rows and target those classnames with the bg-color.
However, maintaining classnames is not very convenient if the rows change frequently.

I would like to find out if JavaScript could assign classnames to alternate rows when IE8 is detected.
This post was spurred by a request in the CSS forum. I don’t know if the poster is interested in JS or not, but I would like to have this in my “toolbox” for the benefit of those who “never say die.” :slight_smile:

Fair confession: I do not speak JavaScript so this is a “will someone please do this for me” request. With luck, and depending on how clearly it’s explained, I’ll pick up a byte of JS knowledge in the process. Fingers crossed :slight_smile:

NOTE: the classname .altie8 could be an ID if necessary.


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>Color Alt Rows - IE8</title>
<!--
The goal is for JavaScript to allow targeted rows to be assigned a background-color when IE8 is detected.
This demo expects alternate rows (odd or even) to be colored.
A thought... by assigning the parent container a particular class (like altie8 in this example), perhaps the script could work with HTML tableware, divs and list items (however the rows were built).
The display would need to refresh when a row was added or deleted.
-->
    <style type="text/css">

table {
    border:1px solid #aaa;
    border-spacing:0;
    margin:0 auto;
}
td {
    border-left:1px dotted #ccc;
    border-top:1px solid #aaa;
    width:100px;  /* TEMP for TESTING */
    height:12px;  /* TEMP for TESTING */
    padding:8px;
}
tr:first-child td {border-top:0;}
td:first-child {border-left:0;}
tr:nth-child(odd) {background-color:#ffd;}  /* might want to comment this line out when testing JS */

    </style>
<!-- Locate at bottom of page?  Might want to remove IE8 restriction while testing JS. -->
<!--[if IE 8]>
<script type="Javascript">
  there is no js at this time
</script>
<![endif]-->

<!--[if IE 8]>
<style type="text/css">
.altie8 .alt {background-color:#ffd;}
</style>
<![endif]-->
</head>
<body>

<table>
    <tbody class="altie8">
        <tr class="alt">  <!-- I would propose that these classes are not normally present in the HTML and should be added to odd or even rows by JS when IE8 is detected -->
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr class="alt">
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr class="alt">
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
    </tbody>
</table>

</body>
</html>


If and only if you use PHP then maybe you could consider adding the following solution to your toolbox:


<?php
  /* PHP Solution: */ 
  $sp = "http://www.sitepoint.com/forums/showthread.php?1217663-Color-Alternate-Rows";

?><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Color Alt Rows - IE8</title>
<style type="text/css">
 table {clear:both; border:1px solid #aaa; border-spacing:0; margin:0 auto; font-size:0.88em;}
 td    {border-left:1px dotted #ccc; border-top:1px solid #aaa; width:100px; height:12px; padding:8px;}
 h3    {text-align:right; margin:0 0}
 h4    {float:left; margin:0 0 2em 0;}
</style>
</head>
<body>
  <h3><a href="<?=$sp;?>"> SitePoint Discussion </a> </h3>

  <h4>
    Change trailing modulus parameter to highlight selected rows<br />
    http://www.johns-jokes.com/downloads/sp-c/color-table-rows/index.php?modulus=7
  </h4>

  <div>
    <?php 
      // check and set default rows
      $modulus = isset($_GET['modulus']) ? $_GET['modulus'] : 4; 
      define('ROW_CHANGE', $modulus);

      echo '<table><tbody>';
        for ($i2=0; $i2<24; $i2++):
          if(0 === $i2 % ROW_CHANGE):
            echo '<tr style="background-color:#eee">';
            echo '<td>' .$i2 .'</td>';
          else:
            echo '<tr>';
            echo '<td></td>';
          endif;    

          echo '<td></td> <td></td> <td></td> <td></td> <td></td> <td></td>';

          echo '</tr>';
        endfor;    
      echo '</table>';
    ?>
  </div>    

  <div>
    <?php highlight_file(__FILE__);?>
  </div>
</body>
</html>

Try changing the trailing modulus parameter to only highlight the selected rows:

http://www.johns-jokes.com/downloads/sp-c/color-table-rows/index.php?modulus=7

Don’t have much experience in Jquery, but just doing a bit of googling.

http://stackoverflow.com/questions/8128581/alternate-row-colors-using-jquery

3rd post down.

<style>
    /* tr:nth-child(even)  RLM2008: Guessing you could leave in tr:nth-child(odd) {background-color: white;} for non ie8 browsers */
    tr.even { background-color: white; }  // RLM2008: This would be solely for ie8
    /* tr:nth-child(odd) */
    tr.odd { background-color: black; }
</style>
<script>
    $(function(){
        // Apply to each table individually and make sure nothing is doubleclassed
        // if you run this multiple times.
        $('table').each(function() {
            $('tr:odd',  this).addClass('odd').removeClass('even');
            $('tr:even', this).addClass('even').removeClass('odd');
        }
    });
</script>

Another result came up with this.

http://code-tricks.com/detect-ie7-and-ie8-browsers-using-jquery/

if (!jQuery.support.leadingWhitespace){
        //Write your code for IE7 and IE8 browsers
    }

Again guessing but I would think you could possibly wrap this feature test around the above code.

I’m sure better answers will follow.

Here’s a solution, although in its current state, all browsers will download the JS (not a biggie, IMHO). It’ taken from a JS sample by Felgall around here, though the link I have to that thread is now broken. I also used a little hack for IE8 that I found online, but of course, CCs can be used instead.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>Color Alt Rows - IE8</title>
<!--
The goal is for JavaScript to allow targeted rows to be assigned a background-color when IE8 is detected.
This demo expects alternate rows (odd or even) to be colored.
A thought... by assigning the parent container a particular class (like altie8 in this example), perhaps the script could work with HTML tableware, divs and list items (however the rows were built).
The display would need to refresh when a row was added or deleted.
-->
    <style type="text/css">

table {
    border:1px solid #aaa;
    border-spacing:0;
    margin:0 auto;
}
td {
    border-left:1px dotted #ccc;
    border-top:1px solid #aaa;
    width:100px;  /* TEMP for TESTING */
    height:12px;  /* TEMP for TESTING */
    padding:8px;
}
tr:first-child td {border-top:0;}
td:first-child {border-left:0;}
/*tr:nth-child(odd) {background-color:#ffd;} */

@media \\0screen { /*hack for ie8: http://dimox.net/personal-css-hacks-for-ie6-ie7-ie8/*/
	.alt {background-color:#ffd;}
}
</style>

</head>
<body>

<table>
    <tbody>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
    </tbody>
</table>

<script>
var tables = document.getElementsByTagName('table');
for (var i = 0, ii = tables.length; i < ii; i++) {
   var bodies = tables[i].tBodies;
   for (var j = 0, jj = bodies.length; j < jj; j++) {
      var rows = bodies[j].rows;
      for (var k = 1, kk = rows.length; k < kk; k+=2) {
         rows[k].className = 'alt';
      }
   }
}
</script>

</body>
</html>

Maybe some bad practices. Conditionally loading jquery seems a bit off. As I say don’t really use Jquery

Anyway working on your code between </style> and </head>

You’ll need jquery-1.11.1.min.js from the jquery site in an appropriate folder. js/jquery-1.11.1.min.js might be better.

<!-- Locate at bottom of page?  Might want to remove IE8 restriction while testing JS. -->
<!--[if IE 8]>
<script src="jquery-1.11.1.min.js" type="text/javascript"></script>
<script>
$(document).ready(function() {
  $(function(){
    $('table').each(function() {
      $('tr:even', this).addClass('odd');
    });
  }); 
});
</script>
<![endif]-->

<!--[if IE 8]>
<style type="text/css">
.odd { background-color: red; }
</style>
<![endif]-->

Have set the odd class to red, just to check that it is only applying to ie8

Example
http://pixel-shack.com/rpgdigit/ZebraStripes.html

Off Topic:

Using jQuery in this situation is a bit like buying a whole hardware store when you need a hammer. Fair enough if you are already using it on a site, but still, it’s nice to do this with just the code required. Just sane. :slight_smile:

Fair point:)

You indeed don’t need jQuery for this, but neither is a CSS hack necessary:


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Color Alt Rows - Cross-browser</title>
<style>
table {
    border:1px solid #aaa;
    border-spacing:0;
    margin:0 auto;
}
td {
    border-left:1px dotted #ccc;
    border-top:1px solid #aaa;
    width:100px;  /* TEMP for TESTING */
    height:12px;  /* TEMP for TESTING */
    padding:8px;
}
tr:first-child td {
    border-top:0;
}
td:first-child {
    border-left:0;
}
tr:nth-child(odd),
.alt {
    background-color:#ffd;
}
</style>

</head>
<body>

<table>
    <tbody>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
        <tr>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
            <td></td>
        </tr>
    </tbody>
</table>

<script>
function setClassAlternately() {
        if (document.documentMode == 8) { // documentMode is strictly IE8+ proprietary
        var tables = document.getElementsByTagName('table');
        for (var i=0; i<tables.length; i++) {
           var bodies = tables[i].tBodies;
           for (var j=0; j<bodies.length; j++) {
              var rows = bodies[j].rows;
              for (var k=0; k<rows.length; k+=2) { // k=0 --> odd rows
                 rows[k].className += ' alt';
              }
           }
        }
    }
}
setClassAlternately();
</script>

</body>
</html>

To have the table repainted after an Ajax update of it, simply call the setClassAlternately() again. If it concerns a static page, the Javascript can look like this:


<script>
if (document.documentMode == 8) { // documentMode is strictly IE8+ proprietary
    var tables = document.getElementsByTagName('table');
    for (var i=0; i<tables.length; i++) {
       var bodies = tables[i].tBodies;
       for (var j=0; j<bodies.length; j++) {
          var rows = bodies[j].rows;
          for (var k=0; k<rows.length; k+=2) { // k=0 --> odd rows
             rows[k].className += ' alt';
          }
       }
    }
}
</script>

Hey Ralph,

Just wondering: what is your gripe with jQuery here?
Is it the size?

Actually, the (core of the) script can be shorter and simpler:


<script>
if (document.documentMode == 8) { // documentMode is strictly IE8+ proprietary
    var tables = document.getElementsByTagName('table');
    for (var i=0; i<tables.length; i++) {
        var rows = tables[i].rows;
        for (var k=0; k<rows.length; k+=2) { // k=0 --> odd rows
         rows[k].className += ' alt';
        }
    }
}
</script>

I don’t wanna answer for Ralph, but I have noticed that the budget tablets are pretty slow. And even iPads sometimes need some time to process large Javascript files. The size is not really a problem, especially not the minified jQuery files, but they still have to be processed.

More the principle of it. :slight_smile:

It’s a pity that one can only edit posts for 30 minutes, otherwise this post would not have been necessary.

There is an unexpected issue with IE8 and CSS3 selectors. This way, the CSS breaks in IE8:


tr:nth-child(odd),
.alt {
    background-color:#ffd;
}

This way it works:


tr:nth-child(odd) {
    background-color:#ffd;
}
.alt {
    background-color:#ffd;
}

Just so you know.

Hi Ron,

This will work as you require:

.odd {
  background: red;
}

<!--[if IE 8]>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script>
    $("tr:odd").addClass("odd");
  </script>
<![endif]-->

Complete code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8">
    <title>Color Alt Rows - IE8</title>
    <style type="text/css">
      table {
        border:1px solid #aaa;
        border-spacing:0;
        margin:0 auto;
      }
      td {
        border-left:1px dotted #ccc;
        border-top:1px solid #aaa;
        width:100px;  /* TEMP for TESTING */
        height:12px;  /* TEMP for TESTING */
        padding:8px;
      }
      tr:first-child td {border-top:0;}
      td:first-child {border-left:0;}

      .odd {
        background: red;
      }
    </style>
  </head>
  <body>
    <table>
      <tbody>
        <tr>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
        </tr>
        <tr>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
        </tr>
        <tr>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
        </tr>
        <tr>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
        </tr>
        <tr>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
          <td></td>
        </tr>
      </tbody>
    </table>

    <!--[if IE 8]>
      <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
      <script>
        $("tr:odd").addClass("odd");
      </script>
    <![endif]-->
  </body>
</html>

Demo

Hope that helps.

What’s a budget table?

The gzipped version of jQuery 1.9.1 is 54.4 KB, so as you say, size is not the issue. I don’t really understand what you mean by “have to be processed”.

I see where you’re coming from. Granted, there are a lot of overly-bloated WordPress sites, which use twenty libraries for unnecessary special effects and where every plugin pulls in its own version of jQuery.
Saying that though, for me, code readability (and thus maintainability) trumps most things.

Compare:

<script>
if (document.documentMode == 8) { // documentMode is strictly IE8+ proprietary
    var tables = document.getElementsByTagName('table');
    for (var i=0; i<tables.length; i++) {
        var rows = tables[i].rows;
        for (var k=0; k<rows.length; k+=2) { // k=0 --> odd rows
         rows[k].className += ' alt';
        }
    }
}
</script>

With:

<!--[if IE 8]>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script>$("tr:odd").addClass("odd");</script>
<![endif]-->

For me the second version is considerably more readable.

I happened across this document recently, which outlines the different workarounds jQuery implements to squash various bugs (even in modern browsers). I would encourage people to read it.

As it says:

A solid DOM library, like jQuery, is a great companion if you’re interacting with the DOM. It means you don’t have to become a deep subject matter expert on all things DOM and your users get predictable support & familiar APIs to tie into.

This line from youmightnotneedjquery is worth repeating… “[Before discounting it] At the very least, make sure you know what jQuery is doing for you, and what it’s not.”

You are comparing two totally different things - your first example is looking at the actual code while the scrond is looking at a script tag that calls the code.

If you are going to compare like with like then the comparison should be between the following two where the first is more readable

<!--[if IE]>
  <script src="stripedTable.js"></script>
<![endif]-->
<!--[if IE]>
  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
  <script>$("tr:odd").addClass("odd");</script>
<![endif]-->

or alternatively compare

var tables = document.getElementsByTagName('table');
    for (var i=0; i<tables.length; i++) {
        var rows = tables[i].rows;
        for (var k=0; k<rows.length; k+=2) { // k=0 --> odd rows
         rows[k].className += ' alt';
        }
    }

to the 54.4k content of http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js with $(“tr:odd”).addClass(“odd”); tacked on the end.

Again the first is more readable.

Note that with IE7 and earlier now dead IE8 is the only browser that supports conditional comments so version checking is now unnecessary.

A budget tablet (not a table) is a cheap tablet (touch screen device). The market is getting flooded with them – Android OS tablets for half the price or less of what Samsung tablets cost.

Unzipped and implemented. I have one of those budget tablets, bought on purpose to see how the things that I make do on them. For one particular site, I have native/vanilla Javascript set the height of one container the same as the article container, because there was no other reasonable alternative. For that budget tablet, I had to set a delay (setInterval), otherwise it couldn’t keep up.

Code readability is important, but I find the script I gave very readable as well. And native JS offers me more precise methods on some occasions. It’s not that I oppose the use of jQuery. Not at all. I used it myself on occasion, e.g. for sortable tables. But to load the library just to have the table rows colored alternately in IE8 as well, that is off-balance, IMO.

Squashing bugs can be a good reason to use jQuery. But the future is native JS – browsers are getting better and better, and the native JS methods are getting easier and easier. Pretty soon, we won’t need an iteration as in for (var i=0; i<tables.length; i++) anymore. As the article in your signature eloquently explains. And I have another article: http://toddmotto.com/is-it-time-to-drop-jquery-essentials-to-learning-javascript-from-a-jquery-background/.

My conclusion is that the use of jQuery must be weighed against the benefits. And in this case of the alternating rows coloring, my choice would clearly be the native JS method.

I linked to the wrong web page. This is the one, by the same author, that shows that jQuery slows things down considerably: https://speakerdeck.com/toddmotto/demystifying-javascript-you-dont-need-jquery. Especially for mobile devices, which almost all have modern browsers anyway, and taking into consideration that even 4G is relatively slow, in practice, and expensive, the speed is an argument to consider.

Sorry for the delay responding to everyone’s posts. First and foremost, thank you John_Betong, RLM2008, ralph.m, Frank S, and Pullo for pitching in. John, you were the first to respond, but I don’t expect to use PHP. Someone else might have a dynamic environment where your code would be perfect, but not me :slight_smile: . My thoughts were very simple.

RLM2008, I made a mistake when I did not specify vanilla JavaScript as the code of choice. Turns out the jQuery code posted by Pullo is so glaringly simple that I feel embarrassed that I didn’t pursue learning it a year ago. It can’t be beat for readability and ease of scripting. My inner aversion to bloatware has fueled my hesitation to use the jQuery library for dirt simple functions like the one I posted in this thread. I can see that it is incredibly easy to understand and write, but it still requires the whole library… That said, I doubt that I will ever have the time and intellect to learn real JavaScript to a level of proficiency that I would like, so jQuery is my best hope for this type of scripting.

Ralph took the path that I had intended to request and threw in an IE hack for entertainment. I loved it :lol: Wouldn’t recommend the hack to our posters, but between friends, it was very cool. :slight_smile: I agree with his analogy about buying a hardware store when one only wants a hammer. I was thinking simpler and lighter than jQuery. His JS was well formatted, to the point and readable, plus his IE hack worked like a champ. :slight_smile:

Frank S followed up with a hackless solution that also showed me how to set up the script as a function that could be called again to recolor the lines without reloading the page and also posted a “standalone” version, then improved it.

BTW, Frank, the unexpected issue that you ran into is a design specification of CSS. If a UA finds an invalid selector, it is supposed to disregard the whole thing. That’s why the IE8 acceptable line had to be separated from the CSS3 selector as you demonstrated, otherwise, IE8, being a good browser, would disregard both.

Then of course Master Pullo posted the jQuery one line solution that left me feeling guilty about my JS ignorance. I am convinced that he remembered my simple foray into jQuery a year ago and my little “var viewer” that actually worked (!) and he was helpfully nudging me back in that direction. Thanks, Pullo.

The jQuery solution has one annoying flaw, though. The colored rows “flash” when the page is reloaded. Probably, in real life that wouldn’t matter, but it does annoy me. I assume that the “flash” is caused by the processing time required of the jQuery library. The vanilla JavaScripts work perfectly without flashing. As a result, I’ll use (and offer) the JavaScript solution if anyone is interested.

There is one more thing that I had requested that wasn’t addressed. (It was easy to skip considering the tableware that I used for the example.) I do not know how to apply that solution to other tags and would like to. For example, suppose I had a container with a series of paragraphs and wanted to alternately color the paragraphs. How could I apply that code to the paragraphs?

<div class=“altie8”>
<p>I am an odd paragraph<p>
<p>I am an even paragraph<p>
<p>I am an odd paragraph<p>
<p>I am an even paragraph<p>
<p>I am an odd paragraph<p>
<p>I am an even paragraph<p>
</div>

We cannot presume that the <div> is a top level div or the only one on the page. That is why I wondered if the script could be written to home in on a classname and color the immediate children (whatever they happened to be: tr, div, li, etc) within that parent container. (I could have actually used this solution on divs several months ago.)

Would anyone like to take a stab at making the script more ‘generically applicable’ based on a parent container’s classname, maybe?

See, that’s where I disagree.
In a lot of cases, it makes sense to simply include jQuery on a per project basis and use the functionality and simplified syntax it offers you.

Oops. Completely misread that. Sorry! That is also a good point about less powerful devices.

For an isolated piece of functionality like this, I agree.
However, it doesn’t normally take long until you want to add another feature here, another one there, and pretty soon you get to the point where you would be better off including jQuery one, then taking advantage of it.

I added a new link to my signature :slight_smile:

Sorry for hijacking the thread Ron. I’ll shut up now.

Here you go:


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Demo alternating coloring</title>
<style>
.altie8_oddChild {
    background-color: pink;
}
table {
    width: 100%;
    border-collapse: collapse;
}
td {
    height: 15px;
    border: 1px solid black;
}
</style>
</head>
<body>
    <div class="altie8">
        <p>I am an odd paragraph</p>
        <p>I am an even paragraph</p>
        <p>I am an odd paragraph</p>
        <p>I am an even paragraph</p>
        <p>I am an odd paragraph</p>
        <p>I am an even paragraph</p>
    </div>

    <table class="altie8">
        <tbody>
            <tr>
                <td>I am the first cell in an odd table row</td>
                <td>I am the second cell in an odd table row</td>
            </tr>
            <tr>
                <td>I am the first cell in an even table row</td>
                <td>I am the second cell in an even table row</td>
            </tr>
            <tr>
                <td>I am the first cell in an odd table row</td>
                <td>I am the second cell in an odd table row</td>
            </tr>
            <tr>
                <td>I am the first cell in an even table row</td>
                <td>I am the second cell in an even table row</td>
            </tr>
            <tr>
                <td>I am the first cell in an odd table row</td>
                <td>I am the second cell in an odd table row</td>
            </tr>
            <tr>
                <td>I am the first cell in an even table row</td>
                <td>I am the second cell in an even table row</td>
            </tr>
        </tbody>
    </table>
<script>
var altie8s = document.querySelectorAll('.altie8'); // no IE8 support for getElementsByClassName; mind the dot
for (var i=0; i<altie8s.length; i++) {
    var altie8 = altie8s[i];
    if (altie8.tagName == 'TABLE') { // must be uppercase
        var altie8_elem_children = altie8.getElementsByTagName('tr');
    }
    else {
        var altie8_elem_children = altie8.getElementsByTagName('*');
    }
    for (var k=0; k<altie8_elem_children.length; k+=2) {
        altie8_elem_children[k].className += ' altie8_oddChild';
    }
}
console.log(altie8_elem_children.length);
</script>
</body>
</html>

The reason for the if else statement is that the counting of the child elements of tables is very different from normal parent elements. Removing the tbody tag does not affect that, because browsers put it in again themselves, as you can see in Firebug – the nr. of child elements stays the same.