简体   繁体   English

JavaScript递归节点等效功能不起作用

[英]JavaScript Recursive Node Equivalence Function Not Working

I'm testing the following code in Chrome Dev Tools and it keeps returning true even when two nodes are not equivalent. 我正在Chrome开发工具中测试以下代码,即使两个节点不相等,它也会一直返回true。 Sample nodes are below. 示例节点如下。 Only Div1 & Div4 are equal. 只有Div1和Div4相等。 I'm pretty confident that I'm recursively touching all nodes, but I think I'm not setting the variable properly with the 'if', or maybe I need an else somewhere- am a little lost and have tried a bunch of things. 我非常有信心我会递归地接触所有节点,但是我认为我没有使用'if'正确设置变量,或者我可能需要在其他地方放置-有点迷失了,尝试了很多方法。

var htmlStrings = [
    '<div id="one">Some<span>node <em>contents</em> for</span>comparison</div>',
    '<div id="two">Some<span>node contents for</span>comparison</div>',
    '<div id="one">Some<span>node <strong>contents</strong> for</span>comparison</div>',
    '<div id="four">Some<span>node <em>contents</em> for</span>comparison</div>'
];

var div1 = document.createElement('div');
div1.innerHTML = htmlStrings[0];
document.body.appendChild(div1);

var div2 = document.createElement('div');
div2.innerHTML = htmlStrings[1];
document.body.appendChild(div2);

var div3 = document.createElement('div');
div3.innerHTML = htmlStrings[2];
document.body.appendChild(div3);

var div4 = document.createElement('div');
div4.innerHTML = htmlStrings[3];
document.body.appendChild(div4);


function nodeEquivalence(node1, node2) {
    var passed = false;


        if (node1.nodeType === node2.nodeType) {
            if ((node1.tagName === node2.tagName || node1.nodeValue === node2.nodeValue)) {
               passed = true;
            } 
        }

        node1 = node1.firstChild;
        node2 = node2.firstChild;
        while (node1 && node2) {
           nodeEquivalence(node1, node2);
            node1 = node1.nextSibling;
            node2 = node2.nextSibling;

        }

        return passed;

}


console.log(nodeEquivalence(div1, div2));
console.log(nodeEquivalence(div1, div4));

Here's an implementation that seems to work for your test cases. 这是一个适用于您的测试用例的实现。 This uses recursion to test child trees. 这使用递归来测试子树。 It is specifically coded to handle elements, documents, document fragments, text nodes and comment nodes. 它专门编码为处理元素,文档,文档片段,文本节点和注释节点。 Support for other types of nodes could be added. 可以添加对其他类型节点的支持。

function nodeEquivalence(node1, node2) {
    var ch1, ch2, nType;

    // OK to have both node1 and node2 not exist, but only if both are missing
    if (!node1 || !node2) {
        return node1 === node2;
    }

    // must be same nodeType
    ntype = node1.nodeType;
    if (ntype !== node2.nodeType) {
        return false;
    }
    // if there is a tagName, must be same tagName
    if (node1.tagName && node1.tagName !== node2.tagName) {
            return false;
    }
    switch(ntype) {
        // nodes that have children
        case 1:   // element node
        case 9:   // document node
        case 11:  // document fragment node
            // check equivalence on each corresponding child
            ch1 = node1.firstChild;
            ch2 = node2.firstChild;
            while (ch1 && ch2) {
                if (!nodeEquivalence(ch1, ch2)) {
                    return false;
                }
                ch1 = ch1.nextSibling;
                ch2 = ch2.nextSibling;
            }
            return nodeEquivalence(ch1, ch2);

        // nodes whose content is nodeValue
        case 3:    // text node
        case 8:    // comment node
            return node1.nodeValue === node2.nodeValue;

        // other types of nodes
        default:
            throw new Error("unsupported type of node");
            break;
    }
}

And, a working demo: http://jsfiddle.net/jfriend00/nruL6fdy/ 并且,一个有效的演示: http : //jsfiddle.net/jfriend00/nruL6fdy/


There were a number of problems with your code logic: 您的代码逻辑存在许多问题:

  1. You were trying to use a single local variable in recursive calls. 您试图在递归调用中使用单个局部变量。 That doesn't work. 那不行
  2. You weren't stopping the comparison as soon as a failure occured. 发生故障后,您不会立即停止比较。
  3. Your logic for if (node1.tagName === node2.tagName) would pass even if tagName didn't exist so you'd never compare the nodeValue . 即使tagName不存在, if (node1.tagName === node2.tagName)逻辑也会通过,因此您永远不会比较nodeValue
  4. Your while loop would miss the case where one node had more children than the other. 您的while循环会漏掉一个节点比另一个节点拥有更多子节点的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM