【问题标题】:TEXT_NODE: returns ONLY text?TEXT_NODE:只返回文本?
【发布时间】:2011-08-30 13:15:43
【问题描述】:

我正在使用 JavaScript 从 DOM 对象中提取所有文本。我的算法遍历 DOM 对象本身及其后代,如果节点是 TEXT_NODE 类型而不是累积它的 nodeValue。
由于一些奇怪的原因,我还得到了类似的东西:

#hdr-editions a { text-decoration:none; }
#cnn_hdr-editionS { text-align:left;clear:both; }
#cnn_hdr-editionS a { text-decoration:none;font-size:10px;top:7px;line-height:12px;font-weight:bold; }
#hdr-prompt-text b { display:inline-block;margin:0 0 0 20px; }
#hdr-editions li { padding:0 10px; }

如何过滤?我需要使用其他东西吗?我只想要文字。

【问题讨论】:

    标签: javascript dom textnode


    【解决方案1】:

    从外观上看,您还从<style> 元素中收集文本。您可能需要检查这些:

    var ignore = { "STYLE":0, "SCRIPT":0, "NOSCRIPT":0, "IFRAME":0, "OBJECT":0 }
    
    if (element.tagName in ignore)
        continue;
    

    您可以将任何其他元素添加到对象映射以忽略它们。

    【讨论】:

    • 谢谢安迪,但我仍然得到一些奇怪的东西,比如:UAstring=navigator.userAgent; if (UAstring.indexOf('iPad')>-1){$('makeHPLink').hide();} function cnnMakeHP() { 还有我应该忽略的标签吗?
    • 这就是我所做的: if (domObj.nodeType == Node.TEXT_NODE) { if (!(domObj.tagName in ignore)) acc += domObj.nodeValue; }
    • @eve:您首先需要忽略检查 - 文本节点没有标签名称,因此您需要在下降到并迭代元素的子节点之前提前检查标签名称。
    【解决方案2】:

    您想跳过style 元素。

    在你的循环中,你可以这样做......

    if (element.tagName == 'STYLE') {
       continue;
    }
    

    您可能还想跳过scripttextarea 等。

    【讨论】:

    • element.tagName 返回一个大写字符串,我犯了同样的错误:-)
    • @Andy 谢谢,我总是忘记这样的事情:)
    【解决方案3】:

    就 DOM 而言,这是文本。您必须过滤掉(跳过)<script><style> 标记。

    【讨论】:

      【解决方案4】:

      [在阅读 OP 的 cmets 后添加的答案对 Andy 的出色回答]

      问题是您会看到元素内部的文本节点,其内容通常不会被浏览器呈现 - 例如 STYLE 和 SCRIPT 标签。

      当扫描 DOM 树时,我假设使用深度优先搜索,您的扫描应该跳过 此类标签的内容

      例如 - 递归深度优先 DOM 树遍历器可能如下所示:

      function walker(domObject, extractorCallback) {
          if (domObject == null) return; // fail fast
          extractorCallback(domObject);
          if (domObject.nodeType != Node.ELEMENT_NODE) return;
          var childs = domObject.childNodes;
          for (var i = 0; i < childs.length; i++)
              walker(childs[i]);
      }
      
      var textvalue = "":
      walker(document, function(node) { 
          if (node.nodeType == Node.TEXT_NODE)
              textvalue += node.nodeValue;
      });
      

      在这种情况下,如果您的 walker 遇到您知道您不希望看到其内容的标签,您应该跳过进入树的那部分。所以walker() 必须这样调整:

      var ignore = { "STYLE":0, "SCRIPT":0, "NOSCRIPT":0, "IFRAME":0, "OBJECT":0 }
      
      function walker(domObject, extractorCallback) {
          if (domObject == null) return; // fail fast
          extractorCallback(domObject);
          if (domObject.nodeType != Node.ELEMENT_NODE) return;
      
          if (domObject.tagName in ignore) return; // <--- HERE
      
          var childs = domObject.childNodes;
          for (var i = 0; i < childs.length; i++)
              walker(childs[i]);
      }
      

      这样,如果我们看到您不喜欢的标签,我们会简单地跳过它及其所有子节点,并且您的提取器将永远不会暴露给此类标签内的文本节点。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-23
        • 2011-08-22
        • 1970-01-01
        • 1970-01-01
        • 2020-10-12
        • 2011-10-29
        相关资源
        最近更新 更多