首页 > 解决方案 > 用混合内容的 HTML 字符串替换 textNode

问题描述

对于此 HTML 节点:

<div><i>foo</i> and <i>bar</i> go ### with <b>baz</b></div>

我想###用另一个节点 ( <u>well</u>) 替换字符串,而不替换整个innerHTMLwrapper div

预期结果:

<div><i>foo</i> and <i>bar</i> go <u>well</u> with <b>baz</b></div>

我的方法是迭代childNodes,只过滤TEXT_NODE带有我想要替换的字符串的元素,并replaceChild使用 DOM 片段替换那些 textNodes 来保存替换的内容:

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这种方式替换 a 不能按预期工作。

虽然我可以手动提取replacedString的每个部分并将其分解为:

`before textNode` / New element / `after textNode` 

并将它们全部拼凑起来,这会创建很多代码(这实际上是我目前正在做的方式,并且我正在尝试一种更聪明的方式,但是片段对解析和插入没有帮助,因为你可以看到)

标签: javascripthtmldom

解决方案


而不是这个:

replacedString = inputChildren[i].nodeValue.replace('###', tag);

您可以使用

var offset = ...indexOf('###');
replacementNode = textnode.splitText(offset); 

然后通过添加

textnode.parent.insertBefore(wrapper, replacementNode);

你可以实现你想要的。


推荐阅读