For this HTML node:
<div><i>foo</i> and <i>bar</i> go ### with <b>baz</b></div>
I would like to replace the string ### with another node (<u>well</u>), without replacing the entire innerHTML of the wrapper div.
Expected result:
<div><i>foo</i> and <i>bar</i> go <u>well</u> with <b>baz</b></div>
My approach was to iterate the childNodes, filter only the TEXT_NODE elements with the string i would like to replace and replace those textNodes with replaceChild using a DOM Fragment to hold the replaced content:
var root = document.querySelector('div'),
tag = "<u>well</u>",
tempFrag = document.createDocumentFragment(),
children = root.childNodes,
replacedString;
for( var i = children.length; i--; ){
if( children[i].nodeType === Node.TEXT_NODE &&
children[i].nodeValue.length > 1 &&
children[i].nodeValue.indexOf('###') != -1 ){
replacedString = children[i].nodeValue.replace('###', tag);
console.log( replacedString );
tempFrag.innerHTML = replacedString;
children[i].parentNode.replaceChild(tempFrag, children[i])
}
}
<div><i>foo</i> and <i>bar</i> go ### with <b>baz</b></div>
As you can see, replacing a textNode in this manner doesn't work as expected.
While I can manually extract each part of the replacedString and break it into:
`before textNode` / New element / `after textNode`
and piece them all in, that would create a lot of code (this is actually the way i'm currently doing it, and am trying to think of a smarter way, but the fragment didn't help with the parsing & insertion as you can see)