Bite Size Standards offers concise web development tutorials, tips, and tricks written by designers and developers who are passionate about web standards. More about us
Update: Special thanks to Anton Peck for his work on this script.
Tired of adding even and odd classes to your tables to distinguish the rows? Well, JavaScript is here to save us!
This script makes all the magic happen:
<script language="JavaScript" type="text/javascript">
window.onload = colorRows;
function colorRows() {
var myTR = document.getElementsByTagName('tr');
for (var i=0;i<myTR.length;i++) {
if (i%2) {
myTR[i].className = 'rowTint';
}
}
}
</script>
Just define the class .rowTint with a style such as
background-color: #ccc; and you are ready to go!
You can see an automatic coloured rows demonstration here.
Commenting is closed for this article.
jacob
: http://www.jacobontwerpt.nl
16 April 2006, 09:35 : Permanent link to comment
Nice solution. Would this work for lists also?
garrett
: http://chrisgarrettmedia.com
16 April 2006, 09:40 : Permanent link to comment
jacob, I’d imagine you’d simply replace
getElementsByTagName('tr');withgetElementsByTagName('li');.Juan Ignacio Serra
: http://www.flusser.com.ar
16 April 2006, 09:46 : Permanent link to comment
Yes, that’s correct, but you also have to consider if you want to color all the lists on your page.
Miguel
: http://tecnoblog.azalorea.com
16 April 2006, 10:11 : Permanent link to comment
Hi,
If you just want to color one of the tables (or lists) instead of using
document.getElementByTagName(‘tr’);(for tables) give the table an id and usedocument.getElementById(‘myTablesId’).getElementsByTagName(‘tr’);Saludos,
Miguel
Pat
: http://patrickyan.net
16 April 2006, 10:46 : Permanent link to comment
Great tip.
Dane
: http://www.brainsideout.com/
16 April 2006, 13:51 : Permanent link to comment
Cool!
I built a similar script for a site that I’ve been working on. To assign the class to every other row, I didn’t use the modulus operand and instead incremented i by two each time through the loop.
The resulting
forcode would be similar to @(var i=1;iDerek Punsalan
: http://5thirtyone.com
16 April 2006, 14:01 : Permanent link to comment
Great tip. This will save a bit of markup. getElementById looks noteworthy as well.
Jeremy Keith
: http://adactio.com/
16 April 2006, 15:22 : Permanent link to comment
What a wonderfully compact little script! Brilliant!
The only little suggestion I’d have would be to put:
if (!document.getElementsByTagName) return;
as the first line in the function to make sure that older browsers don’t choke on it.
Juan Ignacio Serra
: http://www.flusser.com.ar
16 April 2006, 16:45 : Permanent link to comment
Miguel: That’s an excellent complement for the script!
Nice suggestion Jeremy!, that way it can have a graceful degradation.
(Jeremy Keith has just commented on MY article! 0_0 )
Jesus A. Domingo
: http://
16 April 2006, 17:03 : Permanent link to comment
To make it a bit more generic, you could create a function that accepts as parameters the following:
1 – collection of elements (from getElementsByTagName())
2 – odd row classname
3 – even row classname
so if you name it stripeRows(), a call would be:
var mylist = document.getElementById( ‘mylist’ );
stripeRows( mylist.getElementsByTagName( ‘li’ ), ‘oddRow’, ‘evenRow’ );
var mytable = document.getElementById( ‘mytable’ );
stripeRows( mytable.getElemetnsByTagName( ‘tr’ ), ‘oddRow’, ‘evenRow’ );
not much but hope this helps =)
Jesus A. Domingo
: http://
16 April 2006, 17:19 : Permanent link to comment
Also, just to add. For high traffic sites, this helps the server a bit by offloading server-side formatting code to the client. Instead of doing IFs for alternating colros during your data display loop, you just dump it out all at once and have JS do the rest.
jacob
: http://www.jacobontwerpt.nl
17 April 2006, 00:48 : Permanent link to comment
I just tested it on my ul (with an id) and it works perfectly.
nick cowie
: http://nickcowie.com
17 April 2006, 01:18 : Permanent link to comment
Thanks Juan, Miguel and Jeremy, now I have a robust little script to highlight alternating items (tables, lists or any other element.
Matthew Pennell
: http://www.thewatchmakerproject.com/
17 April 2006, 01:22 : Permanent link to comment
Here’s an object literal version (which also adds mouseover/out highlights as well:
Stripe your tables the OO way
Rik Lomas
: http://rikrikrik.com
17 April 2006, 02:10 : Permanent link to comment
Maybe just a small warning. If you’re using window.onload more than once in your javascript then only the last will work, so if you’ve added this to existing javascript then it might not work. Ways around this include:
window.onload = function () {
colorRows();
otherFunction();
...
}
Or by using the addEvent function
Koka
: http://www.4thcube.de/blog
17 April 2006, 02:22 : Permanent link to comment
Won’t this even be part of CSS3?
James AkaXakA
: http://akaxaka.gameover.com/
17 April 2006, 05:38 : Permanent link to comment
Why sure Koka, but why wait until 2034?
Des Traynor
: http://
17 April 2006, 08:52 : Permanent link to comment
This is just a coding question?
Why do you have an if(i%2 ==0) ?
Why not just have the script go …
for (var i=0;i < TR.length;i+=2){ myTR[i].className = 'rowTint';}Juan Ignacio Serra
: http://www.flusser.com.ar
17 April 2006, 09:15 : Permanent link to comment
Because suppose you have 7 rows. When
i=6,iit’s going to be lower than 7 (lenght), but then, you add 2 and myTR8 doesn’t exist.This way (
i%2) you are sure that you are going with an even number.(I hope you understand me!)
Des Traynor
: http://www.minds.nuim.ie/~dez/blog
17 April 2006, 09:37 : Permanent link to comment
Mate, you need to have a think about how for-loops work.
The middle part (the condition) is checked before entering the loop body, so it will bail out when i is 8.
Try it out, see for yourself.
Dave
: http://justunderthesurface.com
17 April 2006, 11:55 : Permanent link to comment
Nice. It automagically colours the rows!
David
: http://slim.climaxdesigns.com
17 April 2006, 18:49 : Permanent link to comment
Nice, much more simple than Zebra tables. I can actually understand this one a bit better and adjust it how i need with my limited jsknowledge.
Justin Wignall
: http://www.somej.net/
18 April 2006, 02:11 : Permanent link to comment
Just a quick note to say that for my home-rolled version of this i use
className += ' rowTint';to allow rows with previous classes assigned to remain. Just a thought.
Justin Wignall
: http://www.somej.net/
18 April 2006, 02:19 : Permanent link to comment
Whilst we’re talking about it, what are peoples thoughts on adding a class to the table you want to colour and then getting all of the tables with that class name and colouring them. (Use a getElementsByClassName script for ease of use)
It adds an extra class attribute to the table but does save having to add an extra line of script to specify each table if you don’t want all of your tables to be alternately coloured.
Andrew Walker
: http://www.moddular.org
18 April 2006, 03:00 : Permanent link to comment
@koka, yes this is available in CSS3 – see the nth-child examples here , although at the moment I don’t think any browser supports this.
Andrew Walker
: http://www.moddular.org
18 April 2006, 03:07 : Permanent link to comment
Huh, you can’t post comments using Opera? What’s up with that? It seems Sébastien Guillon had the same problem
stepan
: http://www.nonplus.net
18 April 2006, 03:25 : Permanent link to comment
Yes, I’d definitely tie this to a class name, s.t. you don’t automatically stripe all tables on the page, and so that each table starts with an odd row.
@
var table myTables[j]; if(table.className.indexOf(“zebra”) >= 0) { var myTR = table.getElementsByTagName(‘tr’); ...var myTables = document.getElementsByTagName(‘table’);
for(var j = 0; j < myTables.length; j++) {
@
Danilo Laurindo
: http://donestudio.com.br/danilo
18 April 2006, 04:46 : Permanent link to comment
Great script! :)
Just another tip here… if you want to apply the “rowTint” class to only one of your tables, simply define its structure on CSS.
As for an example:
table#Example tbody tr.rowTint { background:#ccc; }
It worked pretty fine for me.
Mariam Ayyash
: http://www.elmota.com
18 April 2006, 05:26 : Permanent link to comment
Dude, where’s my comment?
Editors: Whoops there seems to be a buggy TxP plugin...we're on that!
Mariam Ayyash
: http://www.elmota.com
18 April 2006, 05:30 : Permanent link to comment
I just found out that I can only comment using FireFox??!!
It’s just like “if you cannot convince them, confuse them” :)
anyway: my comment:
why not use tableID.rows collection instead? isn’t it easier?
second, I do not prefer Javascript to take care of my style and look, first it takes seconds to appear after loading (and those two seconds are usually when the clients are REALLY paying attention, you know what I mean?) and its a bit of a mess, I hope CSS behaviors will soon be supported by FireFox because they are a life saver, besides that, I would definitely always rely on server side, and one day on CSS3 (one happy day)
Daniel Schierbeck
: http://
18 April 2006, 07:00 : Permanent link to comment
I think the script could be a lot shorter, unless you want flexibility which is not covered by the current version.
window.onload = function colorRows() {
var myTR = document.getElementsByTagName(‘tr’); for (var i=0; i < myTR.length; i++){ if (i%2){ myTR[i].className = ‘rowTint’; } }}
By using an anonymous function you don’t clutter the scope with unnecessary variables/functions.
J. Shirley
: http://www.toeat.com
18 April 2006, 10:50 : Permanent link to comment
My concern with this script is the clobbering of className. Isn’t it better to add it to the class list if it doesn’t already exist?
if ( myTr[i].className )
myTr[i].className += ” rowTint”;else myTr[i].className = ” rowTint”;
I’m not sure if the else is necessary, but it seems reasonable to want to preserve the existing classes for other scripts. Maybe it is better to include an addClass() function to use?
A bit more bloated but probably safer (and reusable).
kentaromiura
: http://mykenta.blogspot.com
18 April 2006, 23:04 : Permanent link to comment
Just 2 things, first you are looking everytime for myTR.length,
you can omit the i%2 control
var myTR = document.getElementsByTagName(‘tr’); var max=myTR.length;for (var i=0;i
Des Traynor
: http://www.minds.nuim.ie/~dez/blog
19 April 2006, 03:19 : Permanent link to comment
function colorRows() {var myTR = document.getElementsByTagName('tr');for (var i=0;i < myTR.length;i+=2){myTR[i].className += ' rowTint';}}Jens Meiert
: http://meiert.com/
19 April 2006, 04:48 : Permanent link to comment
Depending on the document type used, the “language” attribute might not be allowed. And since it does not provide much value, it should be omitted anyway.
Justin Dickinson
: http://www.allmyliesarewishes.com
19 April 2006, 16:30 : Permanent link to comment
if you go with the
@
for (var i=0;i < myTR.length;i+=2)
@
logic you can add a parameter to the function that can be used to set ‘i’ so that you have control over whether the striping will start with the first or second row, such as this:
@
function colorRows(x) {
var myTR = document.getElementsByTagName(‘tr’);
for (var i=x;i < myTR.length;i+=2)
{
myTR[i].className += ’ rowTint’;
}
}
colorRows(0) //first row colored
colorRows(1) //second row colored
@
Mariam Ayyash
: http://www.elmota.com
19 April 2006, 21:48 : Permanent link to comment
Here is my version
function colorRows(tBodyID,classA,classB){
var rowsColl = bodyElement.rows;var bodyElement = document.getElementById(tBodyID);
if(bodyElement){
for(i=0; i < rowsColl.length;i+=2){
rowsColl.className = (i%2==0) ? classA : classB;
}
}
this way, you can control exactly which rows to udergo the coloring, if you devide your table to tbody elements
Des Traynor
: http://www.minds.nuim.ie/~dez/blog
20 April 2006, 09:40 : Permanent link to comment
Mariam, your for-loop increments i by 2 each time, and starts it at zero. So your numbers will be 0,2,4,6,8,10 and so on.
But you are checking if (i%2 ==0) on each iteration anyways. You’re using a ternary expression for something that will ALWAYS evaluate to true. You’re always assigning classA.
It was also pointed out that it’s a bad idea to overwrite an elements class, you should be appending an extra class to it. .
Rein Henrichs
: http://
22 April 2006, 11:47 : Permanent link to comment
Wouldn’t it be better to assign a class to elements that you want to have alternate row colours and then create a general function that passes the class name? Pity there’s no document.getElementsByClass function. Here’s one:
document.getElementByClass = function(needle) {
var xpathResult = document.evaluate(’//*[@class = needle]’, document, null, 0, null); var outArray = new Array(); while ((outArray[outArray.length] = xpathResult.iterateNext())) { } return outArray;}
Then the code to give any element with the correct class alternating rows would be similar to:
window.onload = colorRows(zebra);
for (var i=0;ifunction colorRows(zebraclass) {
var myClass = document.getElementsByClass(zebraclass);
if (myClass)