質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.10%

【JavaScript】for文の結果を1つずつ出力したい

解決済

回答 5

投稿

  • 評価
  • クリップ 0
  • VIEW 3,312

umauman

score 55

前提・実現したいこと

forで繰り返した処理を1つずつHTMLページの任意の場所に表示させたいですが、ループの一番最後の結果しか表示がされません。
すべて表示するにはどのように記述をすべきなのでしょうか?

<p id="render"></p>

<!--body閉じタグの前で外部JSファイルを読み込み-->
<script src="js/script.js"></script>

希望する表示

<p id="render">
0<br>
1<br>
2<br>
3<br>
4<br>
</p>

期待しない表示(これになってしまいます)

<p id="result">
4<br>
</p>

試した記述

いずれも「期待しない表示」になってしまいます。

NGだった記述その①
for (var i = 0; i < 5; i++) {
    document.getElementById('render').innerHTML = i + '<br>';
}
NGだった記述その②
var result = 0;
for (var i = 0; i < 5; i++) {
    result = i + '<br>';
}
document.getElementById('render').innerHTML = result;

例えばdocument.writeを使用すると0~4まですべて表示をさせることはできるのですが、任意の要素の中に入れる方法がわかりません。
なにとぞご教授いただけないでしょうか。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 5

+3

for (var i = 0; i < 5; i++) {
    document.getElementById('render').innerHTML += i + '<br>';
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/26 21:49

    早速回答いただきましてありがとうございます。記述いただいたコードで意図通りの表示になりました。

    キャンセル

+3

 innerHTML

innerHTML は上書きするので、innerHTML に代入する前に連結した文字列を入れる必要があります。

var result = [];
for (var i = 0; i < 5; i++) {
    result.push(i);
}
document.getElementById('render').innerHTML = result.join('<br>');

 insertAdjacentHTML

HTMLを挿入するなら insertAdjacentHTML を使います。
(※innerHTML を += で上書き追加すると、既存のDOM参照は失われるので、お勧めはしません。)

var element = document.getElementById('render');
for (var i = 0; i < 5; i++) {
  element.insertAdjacentHTML('beforeend', i + '<br>');
    result = i;
}

 createDocumentFragment()

ノードを挿入するなら、createDocumentFragment を使います。
今までの方法はHTMLタグを挿入or上書きするものでしたが、ノードで扱う事で特殊文字(<>&"')のエスケープミスによる不具合(XSS)から解放されます。

var df = document.createDocumentFragment(), br = document.createElement('br');

for (var i = 0; i < 5; i++) {
  df.appendChild(document.createTextNode(i));
  df.appendChild(br.cloneNode(false));
}

document.getElementById('render').appendChild(df);

Re: umauman さん

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/26 22:02

    innerHTMLは上書きされてしまうのですね。色々な挿入の記述を教えていただきありがとうございます。特に「insertAdjacentHTML」についてもっと調べてみます。セキュリティに留意するのであればここまで書けるようにならないといけないのですね。色々と調べるきっかけになりそうです。ありがとうございました。

    キャンセル

  • 2017/04/26 23:08

    これも重要そうですね。
    >(※innerHTML を += で上書き追加すると、既存のDOM参照は失われるので、お勧めはしません。)

    キャンセル

+2

NGだった記述はどちらも上書きされて最終的な結果しか表示されていません。
サンプル記述していましたがKosuke_Shibuyaさんが回答されていたのでひかえておきます。
追記しないとだめということですね。

document.getElementById('render').append(i + '<br>');


試していませんが追記なのでこれでもできると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/26 21:51

    ご回答ありがとうございます。いただいたコードですと、<br>の部分はそのまま文字列としてページに表示がされるものの「append」ですと、上書きされずにすべてが表示されることがわかりました。
    勉強になりました。

    キャンセル

checkベストアンサー

+1

 原因

それぞれのコードがなぜ思い通りに動かなかったか説明すると

一つ目は#renderのHTMLを毎回変えているが、
前の処理を上書きしているから最後の処理しか反映されない

for (var i = 0; i < 5; i++) {
    document.getElementById('render').innerHTML = i + '<br>';
}


二つ目も上と同じで変数の中身を毎回上書きしているから

var result = 0;
for (var i = 0; i < 5; i++) {
    result = i + '<br>';
}
document.getElementById('render').innerHTML = result;

 解決策

それぞれの代入の時に=ではなく+=を使うことで前の値に追加で入れることが出来ます。

for (var i = 0; i < 5; i++) {
    document.getElementById('render').innerHTML += i + '<br>';
}
var result = "";
for (var i = 0; i < 5; i++) {
    result += i + '<br>';
}
document.getElementById('render').innerHTML = result;


2017年4月26日 午後9時28分 ソースコードを一部修正

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/26 21:18

    解決策2つ目のコードは実行結果が下記のようになりますよ。
    00
    1
    2
    3
    4
    https://jsfiddle.net/4otqg539/

    キャンセル

  • 2017/04/26 22:06

    「+=」とするところが追加していく上でのポイントなのですね。とても丁寧にわかりやすくご説明いただきありがとうございます!

    キャンセル

+1

var result = '';
for (var i = 0; i < 5; i++) {
    result += i + '<br>'; // 「result = 」では中身を全部上書きしてしまう。
}
document.getElementById('render').innerHTML = result;

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/26 22:09

    ”「result = 」では中身を全部上書きしてしまう。”のコメントありがとうございます。
    「var result = '';」の部分も「0を入れておいたらダメなのかな?」と思ったのですが、他の回答者様の補足でなんとなく理解できた気がします。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.10%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる