【问题标题】:Handle Text Nodes That Are Not Script or Style Elements处理不是脚本或样式元素的文本节点
【发布时间】:2019-07-03 06:44:56
【问题描述】:

我有这个处理所有文本节点的基本代码:

function walk (node) {
    if (node.nodeType == '3') {
        handleText (node)
    }
    node = node.firstChild
    while (node) {
        walk (node)
        node = node.nextSibling
    }
}

不幸的是,这会处理所有文本节点,包括我不想要的<script><style> 等元素。我将我的代码更新为以下内容以忽略这些特定元素:

function walk (node) {
    if (node.nodeType == '3' && node.tagName != 'SCRIPT' && node.tagName != 'STYLE') {
        handleText (node)
    }
    node = node.firstChild
    while (node) {
        walk (node)
        node = node.nextSibling
    }
}

但是,这不起作用。我做错了什么?

【问题讨论】:

    标签: javascript html dom nodes


    【解决方案1】:

    带有nodeType3node 将是一个文本节点。由于听起来您想排除作为 scriptstyle 标签的 children 的文本节点的遍历,因此您应该将测试放在别处 - 如果 tagName 不是,则仅 walk(node) SCRIPT OR STYLE,这样父标签<script>/<style>就不会被迭代:

    function walk (node) {
      if (node.nodeType === 3) {
        handleText (node);
      }
      node = node.firstChild;
      while (node) {
        const { tagName } = node;
        if (tagName !== 'SCRIPT' && tagName !== 'STYLE') {
          walk (node);
        }
        node = node.nextSibling;
      }
    }
    

    (还要注意nodeType 的计算结果为整数,因此您可以改用严格相等比较===

    为避免while 循环和重新分配,您可以考虑改用forEach

    function walk (node) {
      if (node.nodeType === 3) {
        handleText (node);
        return;
      }
      Array.prototype.forEach.call(
        node.childNodes,
        (childNode) => { 
          const { tagName } = childNode;
          if (tagName !== 'SCRIPT' && tagName !== 'STYLE') {
            walk (child);
          }
        }
      );
    }
    

    【讨论】:

    • 感谢您的帮助!我注意到您提供了一个替代示例来“避免while 循环和重新分配”。使用“while 循环和重新分配”不好吗?
    • 这有点基于意见,但可以说是的。当没有重新分配任何内容时,代码更易于阅读 - 在循环的 end 手动重新分配 outer 变量很难一目了然。在大多数情况下,通常可以更好地避免循环;数组方法提供更多抽象,可组合,不需要手动迭代或重新分配。
    【解决方案2】:

    标签检查应该在父节点上:

    function walk(node) {
      if (node.nodeType == 3 && !/SCRIPT|STYLE/.test(node.parentNode.tagName)) handleText(node);
        
      for (node = node.firstChild; node; node = node.nextSibling) walk(node)
    }

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-06
      • 2015-09-17
      • 1970-01-01
      • 2013-04-01
      • 1970-01-01
      • 2020-03-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多