Reputation: 25379
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?
Upvotes: 3
Views: 5517
Reputation: 12679
Are you testing in IE by any chance? Most likely it does work in other browsers.
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).
Upvotes: 2
Reputation: 10514
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.
Upvotes: 0
Reputation: 332791
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.
Upvotes: 0
Reputation: 2882
<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?
Upvotes: 0