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

<div>Hi<b>I</b>am</div>から生成されるtrim()は使用しません<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 に答える