[Greasemonkey] Alternative to innerHTML?

Jeremy Dunck jdunck at gmail.com
Thu Jul 28 00:38:08 EDT 2005


On 7/27/05, Scott Turner <srt19170 at gmail.com> wrote:
> This question doesn't have anything to do with Greasemonkey, but I'm going
> to ask it here anyway since I know there are a lot of Javascript gurus here
> :-).
>  
>  Playtpus has an "Insert HTML" function that works by creating a <DIV>,
> setting innerHTML to whatever the user has entered, and then inserting the
> <DIV> into the DOM tree at the appropriate spot.  This works fine in most
> situations, but fails if you try to do something like insert a new <TD> in a
> table.  The <DIV> wrapping the new HTML breaks the insert -- you end up with
> a <DIV><TD></TD></DIV> in the table instead of a <TD></TD>.
>  
>  So I thought to fix this by creating the <DIV> as before, and then grabbing
> all the child nodes of the <DIV>, promoting them up a level in the DOM tree,
> and then deleting the <DIV>.  This almost works.
>  
>  The problem is that when you create a <DIV> node and set innerHTML to
> something like "<TD>foobar</TD>" you don't actually end up with <TD> child
> nodes.  Apparently the parser that converts the innerHTML to DOM recognizes
> that <TD> inside <DIV> is invalid and never creates the node.  So promoting
> up doesn't work because there's no <TD> node to promote.
>  
>  So my question is whether anyone has any good solutions to this problem, or
> in general how to take text HTML and insert it into a DOM tree.  Any help
> will be much appreciated, thanks!

This is a sledge hammer, and I'm sure someone else will have an
elegant solution, but there aren't really that many different contexts
for HTML containment.  I also assume you're OK being HTML specific. 
For each element type which you want to support insertion on, figure
out a valid containing element and include funcs to generate the
containing context.

So:
function genWrapper(tagName) {
  var context;
  switch(tagName) {
    case 'td' : 
      context = document.createElement('table');
      context.appendChild(document.createElement('tr'));
      context.containingChild = context.firstChild;
    case ....
  }
  return context;
}

And the calling code would do:

var ctx = genWrapper('td');
ctx.containingChild.innerHTML = '<td>gobs of html</td>';
var toInsert = ctx.containingChild.firstChild;


More information about the Greasemonkey mailing list