1

我有以下代码(对于目前的情况,它可以被视为从作为输入提供的有效 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 从字符串中删除属性有更好的实现,但我需要在这里使用上面的函数,而且完整的代码不是用于删除属性,上面只是代码的缩短部分

4

4 回答 4

4

你的result变量有问题。它是未定义的和全局的。在每次递归中,您都会将相同的字符串附加到自身,这也会使其因大量输入而崩溃。(我无法重现任何东西,它会立即因Undefined variable错误而崩溃)

顺便说一句:你的论点是不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, " ")

于 2012-06-05T16:22:12.110 回答
3

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

会发生什么是<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/

于 2012-06-05T16:23:15.497 回答
1

改变

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

至:

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

在演示中工作正常:http: //jsfiddle.net/qtuUA/

于 2012-06-05T16:41:07.840 回答
0

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

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

...

于 2012-06-06T00:23:43.813 回答