When is a TR not a table row?

The answer is: “it depends on which browser you ask”. I ran into a quirk in IE6 while debugging some AJAX-related code this afternoon, and I figured I’d share it. I had some JavaScript code that did something like this:

var t = document.createElement('TABLE');
var tb = document.createElement('TBODY');
var tr = document.createElement('TR');
// create table cells with just numbers in them
for (var i = 0; i < 5; i++) {
	var td = document.createElement('TD');
	td.appendChild(document.createTextNode(i));
	tr.appendChild(td);
} // for i
// ... lots of other magic happens here ...
// later, upgrade those cells to links
for (var i = 0; i < 5; i++) {
	var a = document.createElement('A');
	a.href = 'foo.cfm?i=' + i;
	while (tr.cells[i].childNodes.length > 0)
		a.appendChild(tr.cells[i].firstChild);
	tr.cells[i].appendChild(a);
} // for i
// add the completed row to the table body
tb.appendChild(tr);
// add the table body to the table
t.appendChild(tb);

This worked wonderfully in Firefox and IE7. But when I flipped over to IE6, it broke hard. It would get past the line setting the href for the link, but the while loop would never execute.

I generally try to wait until the last second to add new elements to the DOM, on the theory that modifying them before they are part of the DOM won’t cause the browser to re-render them or even notice them. On a whim, I moved the last two appendChild lines up above the second for loop. Sure enough, IE6 got unbustified.

Apparently, the tr element wasn’t being promoted to being an actual table row until I added it to a table. Before then, it was just an element that happened to have tr for its name. Thus, it didn’t receive the cells magic until after its promotion.

Tricky, tricky.

Published by

Rick Osborne

I am a web geek who has been doing this sort of thing entirely too long. I rant, I muse, I whine. That is, I am not at all atypical for my breed.