2011-07-01 9 views
0

JavaScriptのコードに何らかの問題があります。私は、JavaScriptのメモリリークパターンをオンラインで検索してきましたが、パターンのどれも私のコードに当てはまりません。それは非常に単純なコードですが、クロージャはありません。私は内部関数も持っていません。私の変数はすべてDOMオブジェクトやブール値のような単純な値を保持しています。しかし、どういうわけか、私はFirefox(3.6.11)がフリーズし、IEが私に73行目のメモリが不足していると私に言っているほど多くのメモリをリークすることができます。 DOMツリーに参照がある関数は、toggle、replyForm、およびreplyExpandです。Javascriptのメモリリークが簡単なコード

<script type="text/javascript"> 
function toggle(expandable){ 
    if(expandable.parentNode.getElementsByTagName("ul")[0].className=="hide"){ 
     expandable.parentNode.getElementsByTagName("ul")[0].className="show"; 
     expandable.innerHTML="▼"; 
    } 
    else{ 
     expandable.parentNode.getElementsByTagName("ul")[0].className="hide"; 
     expandable.innerHTML="►"; 
    } 
} 

var previousSpan; 

function replyForm(span,postId,op,commentID){ 
    if(removeForm(span)) 
     return; 
    previousSpan=span; 

    if(span.nextSibling!=null){ 
     span.parentNode.insertBefore(form(span,postId,op,commentID),span.nextSibling); 
    } 
    else{ 
     span.parentNode.appendChild(form(span,postId,op,commentID)); 
    } 
} 

function removeForm(span){ 
    if(previousSpan==null) 
     return false; <-- Out of memory here according to IE 
    if(previousSpan.parentNode.getElementsByTagName("form").length!=0) 
previousSpan.parentNode.removeChild(span.parentNode.getElementsByTagName("form")[0]); 
    var result=(span==previousSpan); 
    if(result) 
     collapse(previousSpan); 
previousSpan=null; 
return result; 
} 

function form(span,postId,op,commentID){ 
var result= 
"<form id=\"commentform\" method=\"post\" action=\"http://innategamer.300mb.us/wp-comments-post.php\">\n"+ 
"<p>Replying to "+op+":</p>\n"+ 
"<p><label for=\"author\">Name *</label><input id=\"author\" type=\"text\" aria-required=\"true\" size=\"30\" value=\"\" name=\"author\"></p>\n"+ 
"<p>Email *<input id=\"email\" type=\"text\" aria-required=\"true\" size=\"30\" value=\"\" name=\"email\"></p>\n"+ 
"<p>Website<input id=\"url\" type=\"text\" size=\"30\" value=\"\" name=\"url\"></p>\n"+ 
"<textarea id=\"comment\" aria-required=\"true\" rows=\"8\" cols=\"45\" name=\"comment\"></textarea>\n"+ 
"<input id=\"submit\" type=\"submit\" value=\"Post Comment\" name=\"submit\">\n"+ 
"<input id=\"comment_post_ID\" type=\"hidden\" value=\""+postId+"\" name=\"comment_post_ID\">\n"+ 
"<input id=\"comment_parent\" type=\"hidden\" value=\""+commentID+"\" name=\"comment_parent\">\n"+ 
"</form>"; 
    var div=document.createElement('div'); 
    div.innerHTML=result; 
    return div.firstChild; 
} 

function replyExpand(span){ 
    if(span.innerHTML.indexOf("▼")!=-1) 
     collapse(span); 
    else 
     expand(span); 
} 

function collapse(span){ 
    if(previousSpan==span) 
     removeForm(span); 
    span.innerHTML=span.innerHTML.replace("▼","►"); 
    while(span.nextSibling!=null){ 
     span=span.nextSibling; 
     if(span.className=="comment-content show"); 
      span.className="comment-content hide"; 
    } 
} 

function expand(span){ 
    span.innerHTML=span.innerHTML.replace("►","▼"); 
    while(span.nextSibling!=null){ 
     span=span.nextSibling; 
     if(span.className=="comment-content hide"); 
      span.className="comment-content show"; 
    } 
} 


</script> 

答えて

0

これは、これらの2つの関数が互いに呼び出すという事実と関係があり、私が知る限り、ifステートメントは、常に真であると考えています。効果的

function removeForm(span) { 
    if (previousSpan == null) return false; < --Out of memory here according to IE 
    if (previousSpan.parentNode.getElementsByTagName("form").length != 0) 
     previousSpan.parentNode.removeChild(span.parentNode.getElementsByTagName("form")[0]); 
    var result = (span == previousSpan); 
    if (result) collapse(previousSpan); // <--------------- 
    previousSpan = null; //        | 
    return result;  //        | 
}       //        | 
          //        | 
function collapse(span) { //        | 
    if (previousSpan == span) removeForm(span); // <-------- 
    span.innerHTML = span.innerHTML.replace("▼", "►"); 
    while (span.nextSibling != null) { 
     span = span.nextSibling; 
     if (span.className == "comment-content show"); 
     span.className = "comment-content hide"; 
    } 
} 

var previousSpan; 

function removeForm(span) { 
    // ... 
    if(span == previousSpan) collapse(previousSpan); 
    // ... 
} 

function collapse(span) { // <---here span is previousSpan, 
     // <-- always true because you're doing if(previousSpan == previousSpan) 
    if (previousSpan == span) removeForm(span); 
    // ... 
} 

// This makes subsequent comparisons in "removeForm()" always true as well, 
// because now it is guaranteed that "span" is the same as "previousSpan" 

のでremoveForm()で一度span == previousSpan、あなたがcollapse()previousSpanを渡しています。最初のものはcollapse()で、受信したものがpreviousSpanに等しいかどうかを確認することです。それは最初に送信するテストだったからです。

+0

ええ、あなたはもう一度です。そして、私は今、本当に馬鹿だと感じます。助けてくれてありがとう、本当に感謝しています。私は昨日このコードを見ていて、それを見ていませんでした。 –

+0

私が得た答えはすべて正しいものでした。なぜなら、それはいくつかの「グラフィック」を含んでおり、問題を示しているからです。再度、感謝します。 –

+0

@Dude Dawg:うん、そこにいた...あなたは大歓迎です。 – user113716

1

無限ループが起こっているように見えます。

removeForm通話collapse

collapse私は細かい歯の櫛で、この上に行くために時間を取るつもりはないremoveForm

+0

ああ、たわごと、私はあなたが正しいと思います!私は今どのように愚かな気分です。ありがとう、私はあなたを助けてくれてうれしいです! –

0

を呼び出します。しかし、removeFormcollapseと呼ばれ、時々removeFormと呼ばれます。私が疑っている最初のことは、これら2つの関数が何らかの形で無限の再帰パターンでお互いを呼び出すことです。

これらの機能のいずれかの先頭にブレークポイントを入れてください。

デバッガで、このブレークポイントに達するたびにコールスタックのサイズを確認します。プログラムがメモリ不足になるまで呼び出しスタックが拡張された場合、StackOverflowに実際のスタックオーバーフローを投稿しました。

+0

あなたは正しいですが、私は実際にこのコードを昨日数時間見ていましたが、私はそれを見つけませんでした。今すぐ正しい答えを選ぶために、すべての答えが正しいので、私はそれに最も多くのテキストを持つ答えを選ぶつもりです。 –

+0

投稿の左側にある数字の横にある「上向き」の矢印をクリックすると、役立つ投稿に投票できます。 –

関連する問題