处理不是脚本或样式元素的文本节点

Posted

技术标签:

【中文标题】处理不是脚本或样式元素的文本节点【英文标题】: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
    

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

【问题讨论】:

【参考方案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)

【讨论】:

以上是关于处理不是脚本或样式元素的文本节点的主要内容,如果未能解决你的问题,请参考以下文章

如何根据子节点删除父节点和/或 css 样式

CSS样式当时 CSS定位 绝对定位

Python Selenium - 根据样式属性单击css元素或包含子元素的文本?推特关注

处理元素(jQuery)

CSS:元素的样式继承者

DOM