Monday, October 24th, 2005

innerHTML Gotchas

Category: Editorial

>There are always a few gotchas here and there. We still find people running into the “IE get requests going into the cache” issue, and there are also issues with innerHTML cross-browser.

Rob Sanheim talked about a recent issue:

After much hardship I’m giving up on trying to use Prototype’s Insertion function for inserting new rows after a specified target row. Everything I try works in Firefox but blows out in IE 6, which is the “supported platform”. After some searching it seems IE has inconsistent support for the insertAdjacentHTML method, and apparently for elements like TR and TBODY IE will throw an exception if the method is called on those methods. In the latest prerelease there is a fix for tbodys, but nothing for tr, and my knowledge dom manipulation fell short when trying to hack that in. If anyone can see how to add that to prototype.js, please let me know. This seems like something that would be commonly done with Rails apps for dynamically adding rows to a table, so its curious that I couldn’t find anything via Google

We can read about this on good ‘ole MSDN: innerHTML property.

The important piece is:

The property is read/write for all objects except the following, for which it is read-only: COL, COLGROUP, FRAMESET, HTML, STYLE, TABLE, TBODY, TFOOT, THEAD, TITLE, TR.

Posted by Dion Almaer at 8:07 am
19 Comments

+++--
3.5 rating from 20 votes

19 Comments »

Comments feed

I ran away screaming when trying to manipulate a tables contents with innerHTML. As with Rob, I was having problems with IE but, mine was a little different. I was able to add the data rows with now problem but, I needed to be able to style the text color differently depending on certain criteria. Mozilla has no problem adding the rows and honoring the css class values. IE, would insert the data but would not honor the css class values of the new rows.

Comment by John Christopher — October 24, 2005

Why does IE have to suck so hard?

Comment by John Beppu — October 24, 2005

You’ll also find that IE throws an unknown error if you attempt set the innerHTML property of a <p> to a value surrounded by a <p></p>. While this is technically not good form, you’d expect this to still render as it does when you hard code the HTML instead of throwing a non-descript exception.

Comment by John — October 24, 2005

I found another one today while doing some innerHTML work on IE and FF. The issue became apparent when replacing some innerHTML which had an onclick event assigned to it. The onclick event remained active even though the tag had been replaced.

i.e.,
click me

function stuff() {
$(‘foo’).innerHTML = ‘gone!’;
return true;
}

The innerHTML content is replaced and the onclick event remains (in IE). Oof.

Comment by Mel — October 25, 2005

Damn your clever yet non-functional ‘preview’!
Anyway, the ‘click me’ text is surrounded by a span with an ID of ‘foo’ and then an A tag with an onclick event that calls stuff();
So there. ;)

Comment by Mel — October 25, 2005

In IE you can’t use innerHTML or outerHTML on tables and instead e to use the “table model”. On MSDN refer to IHTMLTableSection and IHTMLTableRow for methods to insert rows/cells into a table.

See http://msdn.microsoft.com/workshop/author/tables/buildtables.asp

Comment by Steve — October 25, 2005

Today’s hack is brought to us by Microsoft’s lunacy:

var innerHTML = “<tr><td>Hello world!</td></tr>”;

var div = document.createElement(“DIV”);

div.innerHTML = “<table>” + innerHTML + “</table>”;

// Get the tr from the table in the div
var trElem = div.getElementsByTagName(“TR”)[0];

Comment by Brett Fattori — October 28, 2005

Thanks for this forum! I’ve been banging my head against the wall on these very same innerHTML/tables/css problems with IE6 for two weeks and this page has just now popped up in my Google searches. [So, I now know to go a different direction with my elegant new homegrown framework that planned on all MVC views to plug arbitrary HTML into "hook" tags via innerHTML. (sigh)]

Anybody know of any problems with trying to set the innerHTML of a tag that itself was defined dynamically via innerHTML?

Comment by Bruce — October 28, 2005

It seems that many people are complaining on the traffic or the road but remeber that it’s up the driver to find the ways.

Sometimes there are shortcuts and sometimes there aren’t any, but there is also the good-practice factor. Appending child-elements of table with innerHTML or insertAdjacentHTML is bad practice, regardless browser.

Comment by Hakan Bilgin — October 31, 2005

Hakan, what exactly is good practice if i wanted to create new rows on a table dynamically? (arrgh! this DOM thing is hard)

Comment by edward — November 13, 2005

This might help …
http://www.mozilla.org/docs/dom/technote/tn-dom-table/#creating

Comment by edward — November 13, 2005

I’ve written a function based on Steve’s code which basically creates a temporary table in the document and copys all its rows to the “target”. To use it simply call the ieTableInnerHTML(target, rowHTML) where target is the target table/tbody, and rowHTML is the tr code. Sorry for the poor formatting, I couldn’t get linebreak working in the post.

–CODE START–

function ieTableInnerHTML(target, rowHTML) {
/* Vars */
target = $(target);

/* Remove all existing rows */
while (target.rows.length > 0) {
target.deleteRow(0);
}

/* Create temporary table */
var tempDiv = document.createElement("div");
document.body.appendChild(tempDiv);
tempDiv.innerHTML = '<table id="tempTable" style="display: none">' + rowHTML + '</table>';
var tt = $("tempTable");

/* Copy temporary table's rows to target */
for (var i = 0; i < tt.rows.length; i++) {
target.appendChild(tt.rows[i].cloneNode(true));
}

/* Remove temporary table */
Element.remove(tt);
}

–CODE END–

Comment by Paul Chiu — November 14, 2005

Hello,

I didn’t understand all the dollar symbols as shown above in Paul Chiu’s script (I’m not too advanced with javascript), but after slightly modifying it so it didn’t delete the target tbody’s existing rows it works fine in my application:

/* modified from http://www.ajaxian.com/archives/2005/10/innerhtml_gotch.html */
function tableInnerHTML(target, rowHTML) {
/* Removed – why delete them?!
while (target.rows.length > 0) {
target.deleteRow(0);
} */
var tempDiv = document.createElement(“div”);
document.body.appendChild(tempDiv);
tempDiv.innerHTML = ” + rowHTML + ”;
var tt = document.getElementById(“tempTable”);
/* Copy temporary table’s rows to target */
for (var i = 0; i < tt.rows.length; i++) {
target.appendChild(tt.rows[i].cloneNode(true));
}
tt.parentNode.removeChild(tt);
}

Works on IE/Gecko windows. Thanks for your help.

Comment by Kevin — December 16, 2005

If you have SCRIPT tags inside of the code you are adding to an innerHTML, it also won’t run. Also, in some cases if the HTML is malformed in some way (can’t remember exactly how), IE will crash. Gotta love IE and innerHTML. In general, I try not to innerHTML large amounts of complex HTML data in IE or you will have a world of pain. Keep it simple, keep it short.

Comment by Brad Neuberg — December 29, 2005

if you have a script inside…try something like that

el.innerHTML = …whateve you need….

var scripts = el.getElementsByTagName(“script”);
for(var i=0; i

Comment by Gianluca Busan — January 20, 2006

sorry, something strange happens after the submit…
i retry:

if you have a script inside…try something like that
….
el.innerHTML = …whateve you need….

var scripts = el.getElementsByTagName(“script”);
for(var i=0; i

Comment by Gianluca Busan — January 20, 2006

again….
if you have a script inside…try something like that

el.innerHTML = …whateve you need….
var scripts = el.getElementsByTagName(“script”);
for(var i=0; i ≶ scripts.length;i++){
eval(scripts[i].innerHTML);
}

Comment by Gianluca Busan — January 20, 2006

el.innerHTML = …whateve you need….
var scripts = el.getElementsByTagName(”script”);
for(var i=0; i ≶ scripts.length;i++){
eval(scripts[i].innerHTML);
}
====
again the above code doesn’t work with IE.

Comment by Reetha — October 19, 2006

Finally what’s the Solution for the above one…

I have face the similar one here.. please suggest a solution…

var response = response.responseText;
if(response != “false”)
{
document.getElementById(‘suggestSolution’).innerHTML = response;
document.getElementById(‘suggestSolution’).style.display = “block”;
}

In firefox every thing works fine…But In IE its not working… Please help…

Comment by siddik — October 21, 2009

Leave a comment

You must be logged in to post a comment.