3

Update: I just narrowed my problem to this:

Why doesn't this work:

var tmp = document.createElement('tbody');
tmp.innerHTML="<tr><td>hello</td></tr>";

tmp is getting the string hello. the tr and td html is lost (on FireFox). Why is that? and how can I make such html injection work?

Original question:

I need to inject arbitrary HTML after a arbitrary element in arbitrary HTML documents. I came across this method (inject the html string into dynamically generated div, get its firstchild element and insert it in the right place):

var tmp = document.createElement('div'); 
tmp.innerHTML = _injected_html;
var new_w = tmp.firstChild;
var parent = insertion_point.parentNode;
parent.insertBefore(new_w, insertion_point.nextSibling);

The problem is that this does not work when trying to inject table elements. if the injected html is for example

"<tr> <td> table data </td> </tr>"

The _tmp.innerHTML = _injected_html; would not accept it (adding tr under div element).

Any idea how to make this work for any tag?

3
  • is insertion_point guaranteed to have a nextSibling (which might be null otherwise)? Commented Jul 29, 2009 at 20:20
  • 1
    you mean arbitrary not random surely? Commented Jul 29, 2009 at 20:35
  • yep. I meant arbitrary. fixing.... Commented Jul 29, 2009 at 20:42

4 Answers 4

2

Are you testing in IE by any chance? Most likely it does work in other browsers.

Here's why

edit: Wait, you're inserting something into the table that looks like <div><tr><td>... that's not going to work. Why don't you replace the document.createElement('div') by document.createElement('tr'), and remove the <tr> tags from the _injected_html?

Something like this (tested in Firefox):

<script>
var i = 3;

function f() {
    var table = document.getElementById('someTable');
    var children = table.children[0].children;
    var after = children[Math.round(Math.random() * (children.length - 1))];
    var html = "<td>" + i++ + "</td>";

    g(html, after);
}

function g(_injected_html, insertion_point) {
    var tmp = document.createElement('tr'); 
    tmp.innerHTML = _injected_html;
    var new_w = tmp.firstChild;
    var parent = insertion_point.parentNode;
    parent.insertBefore(new_w, insertion_point.nextSibling);
}
</script>

<table id="someTable" onclick="f();">
    <tr><td>1</td></tr>
    <tr><td>2</td></tr>
</table>

The second line of f() is a little awkward, but it gets the first child of the table (which is a <tbody>, and then its children (the actual <tr>s).

Sign up to request clarification or add additional context in comments.

2 Comments

testing on FF at this point. Final solution should be completely cross browser
nice catch, do you know what IE versions are affected by any chance?
0
<div><td><lol/>

..isn't valid HTML! Containers are required for table rows/cols/heads, list items, definition lists and so on. Could you somehow validate the HTML for proper containers before injecting it?

Comments

0

The following javascript will allow you to inject HTML/etc into the local page:

var example = "<p>test</p>"
document.body.appendChild(example); 

That said, you will have to customize the code depending on what you are inserting.

1 Comment

TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
0

For a table, you must insert tr's into tbody. When you write html

<table><tr><td>abc</td></tr></table>

IE, FF, Chrome, Safari at least (don't know about others directly) will modify this to be:

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

Therefore, something like:

var tmp = document.createElement('tr'); 
tmp.innerHTML = "<td>def</td>";
var new_w = tmp.firstChild;
var parent = insertion_point.parentNode;
parent.insertBefore(new_w, insertion_point.nextSibling);

if insertion_point is a tr tag.

But honestly, with Jquery there are more elegant ways of going about this as christina toma notes.

1 Comment

Thanks! Please see the update above. I don't think this is the problem. (+ I can't use jquery)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.