比较父节点和子节点的相似性

时间:2015-01-01 07:34:08

标签: javascript dom comparison nodes

给出以下结构

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

我想把它变成

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

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

基本上,我想做的是检查是否有必要的孩子,如果没有,将其删除,保留所有孩子。所以,所有<p>都是相同的,直的元素,因此只有最顶层的元素才真正做任何事情(在我的代码中,我意识到并非总是如此)。但是,跨度虽然名称相同但并不相同,因为一个人有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。

2 个答案:

答案 0 :(得分:0)

这就是我最终的结果:

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();
}

答案 1 :(得分:-2)

哦,这将是一个有趣的采访问题! 关于解决方案 - 使函数以任何您喜欢的方式遍历DOM,它接收谓词函数作为参数。然后收集一系列通过谓词的项目,然后进行修复&#39;然后。 在你的情况下,谓词显然是一些isChildNecessary函数,你需要实现它。

你打算如何处理第二次传球,第三次传球等等?你什么时候停止?删除一些节点后,您可能最终会遇到另一个无效的节点。国家..只是想一想。