如何封装文本"节点"但是自己没有节点?

时间:2017-03-19 17:54:04

标签: javascript html

我希望使用JavaScript从HTML代码中获取所有文本字符串,并将它们封装在独立标记中作为其父项的子项。

实施例

这是我的HTML:

<div>
    Text Text Text
    <p>
        Text Text
    </p>
    <b>
        Text Text
        <i>
            Text.
        </i>
    </b>
    Text Text Text.
</div>

(代码没有标签,它由页面本身组成一行。)

这就是我想要的:

<div>
    <span>Text Text Text</span>
    <p>
        <span>Text Text</span>
    </p>
    <b>
        <span>Text Text</span>
        <i>
            <span>Text.</span>
        </i>
    </b>
    <span>Text Text Text.</span>
</div>

我一直在寻找如何使用innerHTMLtextContentinsertAdjacentHTML() ...但我不知道如何以可靠的方式做到这一点。

你认为有什么办法吗? (如果可能的话,可以使用vanilla JavaScript。) 提前谢谢。

1 个答案:

答案 0 :(得分:1)

您可以使用TreeWalker(由document.createTreeWalker方法构建)获取所有网页的文本节点,然后使用Node#replaceChild完成其余工作:

function getTextNodes(root) {

  var tw = document.createTreeWalker(root || document.body, NodeFilter.SHOW_TEXT, {
    acceptNode: function(node) {
      return /^(STYLE|SCRIPT)$/.test(node.parentElement.tagName) ||
        /^\s*$/.test(node.data) ? NodeFilter.FILTER_REJECT : NodeFilter.FILTER_ACCEPT
    }
  })

  var result = []
  while (tw.nextNode()) result.push(tw.currentNode)
  return result
}

getTextNodes().forEach(function(n) {
  var span = document.createElement('span')
  n.parentNode.replaceChild(span, n)
  span.appendChild(n)
})

console.log(document.body.firstElementChild.innerHTML)
span {
  border: 1px solid #f00;
}
<main>

  <div>
    Text Text Text
    <p>
      Text Text
    </p>
    <b>
        Text Text
        <i>
            Text.
        </i>
    </b> Text Text Text.
  </div>

</main>