【问题标题】:Comparing a parent and a child node for similarity比较父节点和子节点的相似性
【发布时间】:2015-02-28 00:18:51
【问题描述】:

给定以下结构

<p>
  <p>
    <span>
      <span class="a">
        <p>

我想把它变成

<p>
  <span>
    <span class="a">

是的,第一个块无效,我们将忽略它。这只是一个例子。

基本上,我想做的是检查是否需要任何孩子,如果没有,则删除它,保留其所有孩子。所以,所有&lt;p&gt; 都是相同的、直接的元素,因此只有最上面的元素真正在做任何事情(在我的代码中,我意识到情况并非总是如此)。然而,跨度虽然名称相同,但并不相同,因为一个有class="a",另一个没有类,因此它们都保留了。

如果类名不同,我正在寻找的扩展不仅会起作用,而且任何可能使它实际上不同的属性。

我在想我可以使用node1.attributes === node2.attributes,但这不起作用,即使node1node2 属性的长度为零。此外,node1 === node2node1.isEqualNode(node2)node1.isSameNode(node2) 也都失败了。没错,因为它们不是同一个节点。

那么我怎样才能正确地检查节点是否符合移除条件?

另一个例子,什么时候这实际上是有用的

<p>
  <b>
    Some text
    <u>that is
      <b>bolded</b> <!-- << That <b> is totally useless, and should be removed. -->
    </u>
  </b>
</p>

请不要使用 Jquery。

【问题讨论】:

  • 您首先需要明确定义“必要”子节点是什么。
  • 这就是示例的用途。与父元素相同的元素,并且似乎没有向标记添加任何内容。如原帖所述,外部 CSS 在技术上可能能够改变这一点,但我们忽略了这一点,因为该例外与我的情况无关。从技术上讲,它应该适用于&lt;ul&gt; 内的&lt;ul&gt;,尽管我会为这样的事情设置一个例外。但是,如果一个 ul 具有 classidonclickwidth 或任何其他可用属性,则不应匹配。

标签: javascript dom comparison nodes


【解决方案1】:

哦,这将是一个有趣的面试问题! 关于解决方案——创建一个函数以任何你喜欢的方式遍历 DOM,它接收一个谓词函数作为参数。然后收集一组通过谓词的项目,然后进行“修复”。 在您的情况下,谓词显然是一些 isChildNecessary 函数,您需要实现它。

您打算如何处理第二次和第三次等?你什么时候停下来?删除一些节点后,您最终可能会遇到另一个“无效”状态。只是需要考虑一下。

【讨论】:

  • 很高兴提出面试问题,但是,这不是面试,你的回答也可能是面试问题,而不是答案。
  • 我不敢相信你对此投了反对票。我不会为你写一个实现,我一路帮助你。祝人们以这种态度帮助你,祝你好运。
  • 你甚至没有帮助我继续前进。您所说的只是编写一个遍历 DOM 并比较元素的函数。考虑到我在问如何比较元素,而你告诉我要比较元素,这有什么帮助?我知道我需要做什么,这是我首先寻求帮助的实施/比较。
  • 对a中的属性的每个循环做a,与b比较,反之亦然。但这一切都取决于你想如何比较它们——你的描述很模糊,这本身可能还不够。
【解决方案2】:

这就是我最终的结果:

it = doc.createNodeIterator(doc.firstChild, NodeFilter.SHOW_ALL, null, false);
node = it.nextNode();
while(node){                
    // Remove any identical children        
    // Get the node we can move around. We need to go to the parent first, or everything will be true
    var tempNode = node.parentNode;
    // While we haven't hit the top - This checks for identical children
    while(tempNode && tempNode !== div && tempNode !== doc){
        // If they're the same name, which isn't not on the noDel list, and they have the same number of attributes
        if(node.nodeName === tempNode.nodeName && noDel.indexOf(node.nodeName) < 0 && node.attributes.length === tempNode.attributes.length){
            // Set flag that is used to determine if we want to remove or not
            var remove = true;

            // Loop through all the attributes
            for(var i = 0; i < node.attributes.length; ++i){
                // If we find a mismatch, make the flag false and leave
                if(node.attributes[i] !== tempNode.attributes[i]){
                    remove = false;
                    break;
                }
            }

            // If we want to remove it
            if(remove){
                // Create a new fragment
                var frag = doc.createDocumentFragment();

                // Place all of nodes children into the fragment
                while(node.firstChild){
                    frag.appendChild(node.firstChild);
                }

                // Replace the node with the fragment
                node.parentNode.replaceChild(frag, node);
            }
        }
        // Otherwise, look at the next parent
        tempNode = tempNode.parentNode;
    }

    // Next node
    node = it.nextNode();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-15
    • 1970-01-01
    相关资源
    最近更新 更多