javascript递归函数出错

时间:2012-06-05 15:58:37

标签: javascript jquery html dom nodes

我有以下代码(对于本例,它可以被视为从作为输入提供的有效html字符串中删除属性的函数):

function parse(htmlStr)
{
console.log(htmlStr);
result+="<"+htmlStr.tagName.toLowerCase()+">";
var nodes=htmlStr.childNodes;
for(i=0;i<nodes.length;i++) {
    var node=nodes[i];
    if(node.nodeType==3) {
        var text=$.trim(node.nodeValue);
        if(text!=="") {
            result+=text;
        }
    }
    else if(node.nodeType==1) {
        result+=parse(node);
    }
}
result+="</"+htmlStr.tagName.toLowerCase()+">";
return result;
}

但它没有按预期工作。例如,在以下情况下,当我将以下html作为输入提供时:

<div id="t2">
    Hi I am
    <b>
      Test
    </b>
</div>

返回<div>Hi I am<div>Hi I am<b>Test</b></div>

如果给函数一些大的输入,页面也会崩溃。

注意:我知道有更好的实现使用jQuery从字符串中删除属性,但我需要在这里使用上面的函数&amp;完整的代码也不是用于删除属性,上面只是代码的缩短部分

4 个答案:

答案 0 :(得分:4)

您的result变量有问题。它是未定义的和全球性的。在每次递归中,您都会将相同的字符串附加到自身,这也会导致巨大的输入崩溃。 (我无法重现任何内容,它会立即崩溃Undefined variable错误

BTW:你的论点是htmlStr,它是domNode。而且你没有解析任何东西。请不要使用错误的自我记录变量名称。

更正版本:

function serialize(domElement) {
    var tagname = domElement.tagName.toLowerCase();
    var result = "<"+tagname+">";
//  ^^^       ^ not a +=
    var children = domElement.childNodes;
    for (var i=0; i<children.length ;i++) {
//       ^^^ was also missing
         if (children[i].nodeType == 3) {
             result += children[i].data;
         } else if (children[i].nodeType == 1) {
             result += serialize(children[i]);
//                  ^^ add a child's result here
         }
    }
    result += "</"+tagname+">";
    return result;
}

我不会使用trim(),这会从<div>Hi<b>I</b>am</div>产生<div>Hi <b>I</b> am</div>。您可能会执行.replace(/\s+/g, " ")

之类的操作

答案 1 :(得分:3)

result+=parse(node); - &gt;在你的情况下,你不应该像在那里那样将结果合并到递归中。

<b>递归调用的返回结果会将返回结果附加到现有结果中。如果现有结果为<div>Hi I am且返回的结果为<div>Hi I am<b>Test,那么在递归结束时您有<div>Hi I am<div>Hi I am<b>Test

var result = '';
function parse(htmlStr) {        
    result += "<" + htmlStr.tagName.toLowerCase() + ">";    
    var nodes = htmlStr.childNodes;
    for (i = 0; i < nodes.length; i++) {
        var node = nodes[i];        
        if (node.nodeType == 3) {
            var text = $.trim(node.nodeValue);
            if (text !== "") {
                result += text;
            }
        } else if (node.nodeType == 1) {            
            parse(node);
        }
    }
    console.log(result);
    result += "</" + htmlStr.tagName.toLowerCase() + ">";
    return result;
}

固定小提琴: http://jsfiddle.net/FBnYT/

答案 2 :(得分:1)

更改

result+="<"+htmlStr.tagName.toLowerCase()+">";

为:

var result="<"+htmlStr.tagName.toLowerCase()+">";

在演示中可以很好地使用:http://jsfiddle.net/qtuUA/

答案 3 :(得分:0)

发生崩溃是因为循环控制变量不是本地范围的。因此,除了其他建议的更改:

for( var i = 0; i&lt; nodes.length; i ++)

...