优化JavaScript TreeWalker以复制除特定节点外的所有节点

时间:2019-07-18 03:48:22

标签: javascript

我有以下输入DOM

var inputNode = document.querySelector('.test');

treeWalker = document.createTreeWalker(
  inputNode, NodeFilter.SHOW_ALL, null, false
);
currentNode = treeWalker.nextNode();

var tempDiv = document.createElement('div');
while (currentNode != null) {
  nodeType = currentNode.nodeType;
  if (
    currentNode.tagName && currentNode.tagName.toLowerCase() === 'span' &&
    currentNode.dataset && currentNode.dataset.element && currentNode.dataset.element === "retain"
  ) {
    tempDiv.appendChild(currentNode.cloneNode(true));
    currentNode = treeWalker.nextNode();
  } else if (currentNode.hasChildNodes() === false) {
    tempDiv.appendChild(currentNode.cloneNode(true));
  }
  currentNode = treeWalker.nextNode();
}
<div class="test">
  <font color="#aa533e">
    <font face="Helvetica, serif">
      <font size="1" style="font-size: 8pt">
        <span style="background: #d096ff">Hello <span data-element="retain">World</span></span>
      </font>
    </font>
  </font>
  <font color="#000000">
    <font face="Times New Roman, serif">
      <font size="2" style="font-size: 11pt">This is</font>
    </font>
  </font>
  <b>test</b> example
</div>
一种 bove是我编写的代码,到目前为止效果很好。但我不确定我所采用的方法是否正确。

我只想保留data-element="retain"节点和所有其他文本节点。

预期输出:

<div>
  Hello <span data-element="retain">World</span> This is test example
</div>

1 个答案:

答案 0 :(得分:1)

我认为,使用与您使用的相同的API可以更简单地做到这一点。

它使用document.createTreeWalker的第三个参数,并传递acceptNode函数来过滤要过滤的对象。


var nodeIterator = document.createNodeIterator(
  // Node to use as root
  document.getElementById('someId'),

  // Only consider nodes that are text nodes (nodeType 3)
  NodeFilter.SHOW_TEXT,

  // Object containing the function to use for the acceptNode method
  // of the NodeFilter
    { acceptNode: function(node) {
      // Logic to determine whether to accept, reject or skip node
      // In this case, only accept nodes that have content
      // other than whitespace
      if ( ! /^\s*$/.test(node.data) ) {
        return NodeFilter.FILTER_ACCEPT;
      }
    }
  },
  false
);

// Show the content of every non-empty text node that is a child of root
var node;

while ((node = nodeIterator.nextNode())) {
  alert(node.data);
}

查看更多信息:

  1. TreeWalker

  2. NodeFilter/acceptNode