2013-07-15 17 views
13

<p>, </p>タグの間に置かれたすべてのテキストを書き込むはずのjavascript関数 'doAll'があります。私のコードでは、2つの方法で使用されています。Javascript関数が予期しない動作をする

ページの最後で呼び出すと正しく動作します。ただし、クリック・ボタン・イベントが発生したときにもトリガーする必要があります。なんらかの理由で、今度は何をするのでしょうか?ボタンをクリックすると、最初の<p>...</p> html要素の内部htmlが出力されます。

私の質問は、これらの2つの状況で異なる動作をする理由と、この問題を解決するためにどうすればよいかということです。ここで

<!DOCTYPE html> 
<html> 
    <head> 
     <script> 
      function returnList(x) 
      { 
       return document.getElementsByTagName(x); 
      } 

      function writeList(x) 
      { 
       var i = 0; 

       while (x[i]) 
       { 
        document.write(x[i++].innerHTML + '<br/>'); 
       } 
      } 

      function doAll(x) 
      { 
       writeList(returnList(x)); 
      } 
     </script> 
    </head> 

    <body> 
     <p>XXX</p> 
     <p>YYY</p> 
     <div style = 'background-color: gray;'> 
      <p>YYY</p> 
      <p>XXX</p> 
     </div> 

     <button type = 'button' onclick = "doAll('p')"> 
      Click me! 
     </button> 

     <script> 
      document.write('<br/>'); 
      doAll('p'); 
     </script> 
    </body> 
</html> 

は、 '出力' です:
XXX
YYY
YYY
XXX

XXX
YYY
YYY
XXX

そして、ここではどのような1缶ですボタンをクリックすると表示されます:
XXX

+0

なぜ第1の出力は、8行で構成されていますか?クリックしたように見えるものは早い段階で実行されます。 –

+0

覚えておいてください: 'debugger' +ブラウザ開発ツールは常にあなたの友人です。 – DontVoteMeDown

+0

@LarsEbert:いいえ、それはクリックボタンのためではありません。 4行の追加出力は、コードの最後の6行の結果です。あなたが見ることができるように、doAll関数は、コードの最後のセクションによって自動的にトリガされます。 –

答えて

14

問題は、あなたがあなたのボタンをクリックすると、ページがすでに、レンダリングされていることです。この時点でdocument.write()をトリガすると、ドキュメント全体が無効になります。最初の要素は、関数をトリガしたときにまだ存在する唯一の要素なので、最初の要素が書き込まれます。最初に実行されたdocument.write()の後に他の要素は存在しません。

機能自体もドキュメントには含まれなくなります。あなたはMUSTは、あなただけのテストの理由のためにそれを使用したいdocument.write()との仕事や場合は、何らかの形で「キャッシュ」を一度あなたのデータと出力がそれに持っている:

function writeList(x) { 
    var i = 0, data = ""; 

    while (x[i]) { 
     data += x[i++].innerHTML + '<br/>'; 
    } 

    document.write(data); 
} 
3

document.writeは、現在読み込まれているドキュメントにのみコンテンツを書き込むことができます。ロードされると、少し違った動きをします - https://developer.mozilla.org/en-US/docs/Web/API/document.writeを参照してください。特殊なコンテナ要素とinnerHTMLを使用して、希望する出力を書き出します。

function writeList(list) { 
    var i, result = ""; 
    for (i = 0; i < list.length; i++) { 
     result += list[i].innerHTML + "<br />"; 
    } 
    document.getElementById("myContainer").innerHTML = result; 
} 

http://jsfiddle.net/3yPAW/1/

+0

'for'ループに' if'の必要はありません。 'result + = list [i] .innerHTML +"
";'。 – Amberlamps

+1

削除されました...それを指摘していただきありがとうございます。 –

2

、他の2つの答えがなぜを説明し、私は」あなたはを提案します。これを避ける:

あなたのHTMLを体(または他の要素)のinnerHTMLに追加します。

代わりに

document.write(x[i++].innerHTML + '<br/>'); 

使用

document.getElementsByTagName("body")[0].innerHTML += x[i++].innerHTML + '<br/>'; 

デモ:のみ4のpタグがあるがhttp://jsfiddle.net/MNCbx/

関連する問題