替换标签内的字符时,如何避免在标签内编辑标签

How do you avoid editing tags inside of tags when replacing characters inside of a tag

所以假设你有 HTML 看起来像这样:

<p>This text is <b>bold</b></p>

和这个 Javascript:

var obs = document.getElementsByTagName("p");
var obsreplace = obs[0].innerHTML.replace(/b/gi, "g");
obs[0].innerHTML = obsreplace;

这会将 HTML 更改为:

<p>This text is <g>gold</g></p>

但是如果我想把它改成:

<p>This text is <b>gold</b></p>

并保持粗体标签不变?

所以,两种解决方案,替换为保留匹配组的正则表达式,或者使用 getElementsByTagName?在对元素进行任何操作之前,一定要检查 obs 和 bold 的长度,确保没有错误。

var obs = document.getElementsByTagName("p");
var bold = obs[0].getElementsByTagName("b")[0];
bold.innerHTML = "gold";

var obs = document.getElementsByTagName("p");
var replaceHtml = obs[1].innerHTML.replace(/(<b>).*?(<\/b>)/, "gold");
obs[1].innerHTML = replaceHtml;
<p>This text is <b>bold</b></p>
<p>This text is <b>bold</b></p>

您需要使用 childNodes 和 运行 替换它们中的每一个。这将捕获与元素分开的文本节点。通过递归遍历每个子元素直到只剩下文本节点,您可以安全地 运行 对元素中的所有文本执行替换命令。

function safeReplace(elem, replaceFn){
  let nodes = elem.childNodes, i = -1
  while(++i < nodes.length){
    let node = nodes[i]
    if(node.nodeType == 3){ //signifies a text node
      node.textContent = replaceFn(node.textContent)
    } else {
      safeReplace(node, replaceFn)
    }
  }
}
document.querySelector('button').addEventListener('click', function(){
  safeReplace(document.getElementById('testDiv'), function(str){
    return str.replace(/e/gi, '_E_')
  })
})
<div id="testDiv">
This div has outer content, as well as <p>a paragraph containing a <span>spanned text</span> in the middle</p>More text.</div>

<button>Replace Text</button>