<div><i>foo</i> and <i>bar</i> go ### with <b>baz</b></div>
我想用另一个节点(###
)替换字符串<u>well</u>
,而不替换包装器innerHTML
的整个div
。
<div><i>foo</i> and <i>bar</i> go <u>well</u> with <b>baz</b></div>
我的方法是迭代 childNodes ,仅过滤我要替换的字符串中的TEXT_NODE
元素,然后使用DOM Fragment将这些textNode替换为replaceChild
保留替换的内容:
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>
如您所见,以这种方式替换textNode
不能按预期工作。
虽然我可以手动提取 replacedString 的每个部分并将其分解为:
`before textNode` / New element / `after textNode`
并将它们全部拼凑在一起,将创建大量代码(这实际上是我当前正在执行的方式,并且正在尝试考虑一种更智能的方式,但是该片段对解析和解析没有帮助。如您所见)
答案 0 :(得分:1)
代替此:
replacedString = inputChildren[i].nodeValue.replace('###', tag);
您可以使用
var offset = ...indexOf('###');
replacementNode = textnode.splitText(offset);
然后添加
textnode.parent.insertBefore(wrapper, replacementNode);
您可以实现自己想要的。
答案 1 :(得分:0)
var root = document.querySelector('div'),
tag = document.createElement('u'),
children = root.childNodes,
replacedNode,
idx;
tag.innerHTML = "well";
for( var i = children.length; i--; ){
if( children[i].nodeType === Node.TEXT_NODE &&
children[i].nodeValue.length > 1 ){
idx = children[i].nodeValue.indexOf('###');
if( idx == -1 ) continue;
replacedNode = children[i].splitText(idx);
// remove '###' from the second split textNode ('### with')
replacedNode.nodeValue = replacedNode.nodeValue.replace('###', '');
// put the tag element before the second split textNode
children[i].parentNode.insertBefore(tag, replacedNode);
}
}
<div><i>foo</i> and <i>bar</i> go ### with <b>baz</b></div>