Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/419.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript递归节点等价函数不工作_Javascript_Html_Dom_Recursion - Fatal编程技术网

JavaScript递归节点等价函数不工作

JavaScript递归节点等价函数不工作,javascript,html,dom,recursion,Javascript,Html,Dom,Recursion,我正在Chrome开发工具中测试以下代码,即使两个节点不相等,它也会不断返回true。下面是示例节点。只有Div1和Div4是相等的。我很有信心我会递归地接触所有节点,但我认为我没有用“if”正确地设置变量,或者可能我需要一个别处的变量——我有点迷茫,尝试了很多事情 var htmlStrings = [ '<div id="one">Some<span>node <em>contents</em> for</span>comp

我正在Chrome开发工具中测试以下代码,即使两个节点不相等,它也会不断返回true。下面是示例节点。只有Div1和Div4是相等的。我很有信心我会递归地接触所有节点,但我认为我没有用“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));
var htmlStrings=[
“用于比较的某些节点内容”,
“用于比较的某些节点内容”,
“用于比较的Somenode内容”,
'用于比较的某些节点内容'
];
var div1=document.createElement('div');
div1.innerHTML=htmlStrings[0];
文件.正文.附件(第1部分);
var div2=document.createElement('div');
div2.innerHTML=htmlStrings[1];
文件.正文.附件(第2部分);
var div3=document.createElement('div');
div3.innerHTML=htmlStrings[2];
文件.正文.附件(第3部分);
var div4=document.createElement('div');
div4.innerHTML=htmlStrings[3];
文件.正文.附件(第4部分);
功能节点等效性(节点1、节点2){
var通过=错误;
if(node1.nodeType===node2.nodeType){
if((node1.tagName==node2.tagName | | node1.nodeValue==node2.nodeValue)){
通过=正确;
} 
}
node1=node1.firstChild;
node2=node2.firstChild;
while(节点1和节点2){
节点等效性(节点1、节点2);
node1=node1.nextSibling;
node2=node2.nextSibling;
}
返回通过;
}
log(节点等效性(div1,div2));
日志(节点等效性(div1,div4));

下面是一个似乎适用于您的测试用例的实现。这使用递归来测试子树。它被专门编码来处理元素、文档、文档片段、文本节点和注释节点。可以添加对其他类型节点的支持

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;
    }
}
还有一个工作演示:


您的代码逻辑存在许多问题:

  • 您试图在递归调用中使用单个局部变量。那不行
  • 您没有在发生故障时立即停止比较
  • 即使标记名不存在,
    if(node1.tagName==node2.tagName)
    的逻辑也将通过,因此您永远不会比较
    nodeValue
  • 您的while循环将错过一个节点的子节点多于另一个节点的情况

  • 我的猜测是,您的“标记名”始终为真,因此-它将始终通过。不要使用| |使用&&谢谢。尝试过,但仍然有相同的问题。标记名用于元素,nodeValue用于textNode,因此理论上它们都不能传递。@freezycold-您调用的是
    nodeEquivalence(node1,node2)
    并期望它做一些事情,但不查看其返回值。