Because you are talking about your replacement being anything, and also replacing in the middle of an element's children, it becomes more tricky than just inserting a singular element, or directly removing and appending:
function replaceTargetWith( targetID, html ){
/// find our target
var i, tmp, elm, last, target = document.getElementById(targetID);
/// create a temporary div or tr (to support tds)
tmp = document.createElement(html.indexOf('<td')!=-1?'tr':'div'));
/// fill that div with our html, this generates our children
tmp.innerHTML = html;
/// step through the temporary div's children and insertBefore our target
i = tmp.childNodes.length;
/// the insertBefore method was more complicated than I first thought so I
/// have improved it. Have to be careful when dealing with child lists as
/// they are counted as live lists and so will update as and when you make
/// changes. This is why it is best to work backwards when moving children
/// around, and why I'm assigning the elements I'm working with to `elm`
/// and `last`
last = target;
while(i--){
target.parentNode.insertBefore((elm = tmp.childNodes[i]), last);
last = elm;
}
/// remove the target.
target.parentNode.removeChild(target);
}
example usage:
replaceTargetWith( 'idTABLE', 'I <b>can</b> be <div>anything</div>' );
demo:
- http://jsfiddle.net/97H5Y/1/
By using the .innerHTML
of our temporary div this will generate the TextNodes
and Elements
we need to insert without any hard work. But rather than insert the temporary div itself -- this would give us mark up that we don't want -- we can just scan and insert it's children.
...either that or look to using jQuery and it's replaceWith
method.
jQuery('#idTABLE').replaceWith('<blink>Why this tag??</blink>');
update 2012/11/15
As a response to EL 2002's comment above:
It not always possible. For example, when createElement('div')
and set its innerHTML as <td>123</td>
, this div becomes <div>123</div>
(js throws away inappropriate td tag)
The above problem obviously negates my solution as well - I have updated my code above accordingly (at least for the td
issue). However for certain HTML this will occur no matter what you do. All user agents interpret HTML via their own parsing rules, but nearly all of them will attempt to auto-correct bad HTML. The only way to achieve exactly what you are talking about (in some of your examples) is to take the HTML out of the DOM entirely, and manipulate it as a string. This will be the only way to achieve a markup string with the following (jQuery will not get around this issue either):
<table><tr>123 text<td>END</td></tr></table>
If you then take this string an inject it into the DOM, depending on the browser you will get the following:
123 text<table><tr><td>END</td></tr></table>
<table><tr><td>END</td></tr></table>
The only question that remains is why you would want to achieve broken HTML in the first place? :)