JavaScriptで学ぶ
文系の人にもわかるプログラミング入門

第9章   表を使った要素の整列

前の章で習ったHTMLの表(テーブル)の機能を使って, 目的のJavaScriptのプログラムで扱う要素をきれいに並べる方法を学びましょう。

JavaScriptからの表の生成 ── document.write()の利用

HTMLを使った表の作成方法は一応おわかりいただけたでしょうか。 いつも同じ問題を出すのならば, 単に前の章でみたようなコードをHTMLで書けばよいのですが, 読み込むたびに, あるいはボタンを押すたびに別の問題を表示するためには, JavaScriptの出力として上のようなHTMLのコードを(問題をランダムに変えて)生成する必要があります。 つまり, ランダムに生成した問題を<table>, <tr>, <td>などのタグでうまく囲んで正しいHTMLの文書を(自分で書くのではなく)プログラムで動的に生成してやる必要があります。

それをやってくれるのがプログラム9-1です。 これをウェブブラウザに読み込むと, 図9-1のようなページが表示されます。

図9-1 計算プリントのページ(2×2)

プログラム9-1 example09-01.html 計算問題10

コードの概要

では, このプログラムを「解読」していきましょう。 長いので, 最後までがんばってついてきてください。

HTMLの本体部分は89-90行目の次の2行だけです。

  89  <body onload="keisanPrintHyoji();">
  90  </body>

<body>タグのonload属性に関数keisanPrintHyoji()を指定しているので, このページが読み込まれるとこの関数が実行されます。 このkeisanPrintHyoji()の中で, HTMLページの内容を生成するわけです。

ロード時に呼ばれるJavaScriptの関数keisanPrintHyoji()の処理は大きく2つに分かれます。 まず, 関数mondaiSeisei()を呼んで, 問題を指定した数だけ生成します。 それは18行目でmondaiSeisei()という関数を呼んで行っています。 生成した問題は, 21行目以降で表関連のタグを使って適当な位置に配置します。

問題の生成と記憶

では, さらに詳しく見ていきましょう。 まず, 12行目で新しい配列mondaiを生成します。

  12      var mondai = new Array();

14行目からの次のfor文でmondaiSu個の問題を生成して, それを配列mondaiに代入します。

  14      for (i=0; i<mondaiSu; i++) {
  15          mondai[i] = mondaiSeisei(kotaeNoSaidaiChi);
  16      }

mondai[0]には1問目, mondai[1]には2問目といった具合に記憶されます。 mondaiSuは8行目で定義しているグローバル変数(大域変数)でこの値は2*2, つまり4になっています。 2*2と書いたのは, 2行2列という意図を表したものです。 ここを, 10*2とすれば(ほかのどこも変更せずに)10行2列のプリントができあがるという仕組みです。

HTMLコードの生成

ここまでで問題の生成を終わり, 以下で表示用のHTMLコードの生成に移ります。

  18    var code = '<h2 style="text-align: center;">けいさんれんしゅう</h2>\n';
  19    code += '<table style="margin: auto;">\n';

まず変数codeを宣言して, ここに見出しと<table>タグを代入しています。 変数codeは生成するHTMLコードを(改行を含め)すべて記憶しておくもので, 最後にこの変数の内容を出力してHTMLコードを生成します(30行目)。 codeには文字どおりコードが入っているわけです(「\n」は改行文字を表します)。

  30    document.write(code);

次のforループが重要です。

  20    for (i=0; i<mondaiSu/2; i++) {
  21      code += '<tr><td style="text-align: right;">'
  22        + mondai[i*2] + '</td>'
  23        + '<td>=</td> <td style="width: 20%;"></td>'
  24        + '<td style="text-align: right;">' + mondai[i*2+1]
  25        + '</td> <td>=</td></tr>\n';
  26    }

ループの終了を判定するための変数(ループ変数)iは0から始まり, mondaiSu/2(この場合は2になります)より小さい値の間, 繰り返します。 つまりiが0と1の場合についてループすることになります。

21行目の「code +=」で始まる文は, 次のように書いても同じことになります。

      code = code + '<tr><td style="text-align: right;">' ...

つまり, codeに入っている文字列の後ろに「+=」の後に書いてあるものを連結して, それをもう一度codeに代入するという意味になります。 変数名を2度書かなくても済むので手間が省けるし, 慣れると簡潔でわかりやすくも思えるはずです。

メモ

上のcodeには文字列が入っているので, +の被演算子はいずれも文字列となり, +=は連結の働きをします。 被演算子が, 数値の入っている変数や数字の場合は, +=も「足し算」の意味で使われます。 たとえば, 次のコードの終わりではiの値は3になります。

    var i = 1;
    i += 2; // i = i+2; と同じ

足し算(+)以外の「-」「*」などの演算子についても同様の書き方ができます。 たとえば, 「x -= 3;」は「x = x-3;」と同じです。 ただし, 私たちの経験では「-」と「+」以外は, ほとんど使ったことがありません(プログラムする対象の分野が異なれば, 「*=」や「/=」などを頻繁に使うケースもあるかもしれませんが)。

さて, iが0のときはmondai[0]とmondai[1]に入っている問題が前後の文字列と連結されて, 変数codeに追加されます。 mondai[0]に「7 + 6」mondai[1]に「13 + 4」が入っているとすると次のような文字列がcodeに追加されます。 これは, 前の章の最初でみたHTMLのコード(プログラム8-2)と同じです。

<tr>
  <td style="text-align: right;">7 + 6</td> <td>= </td>
  <td width="20%"> </td>
  <td style="text-align: right;">13 + 4</td> <td>= </td> 
</tr>

同様にiが1の時はmondai[2]とmondai[3]が前後の文字列と連結されてcodeの後ろに付くことになります。

最後に, 表の終わりを示す</table>と採点のための行を付加します。

  27    code += '</table>\n';
  28    code += '<p style="text-align: right;">'
  29      + 'せいかい_____ まちがい _____ </p>';

その下の次の1行がHTMLコードをブラウザに書き出すものです。

  30      document.write(code);

document.write()は文字列を引数として受け取り, その内容をHTMLのコードとしてブラウザに渡します。 ブラウザはこれをウィンドウ内に表示します。 <body>...</body>の間に入るHTMLコードをこのようにして書き出せばブラウザのウィンドウ内に表示されることになります。

別の解法

上の例では<body>タグのonload属性に関数を指定しましたが, 関数keisanPrintHyoji()では, 見出し部分(<h1>...</h1>)を出力せずに問題だけを出力するように定義して, <body>以下を次のようにしても同じページができあがります。

<body>
<h2 style="text-align: center">けいさんれんしゅう</h2>
<script type="text/javascript">
keisanPrintHyoji();
</script>
<p style="text-align; right"> せいかい_____ まちがい _____ </p>
</body>
</html>

問題はランダムに変わるので, 問題部分をHTMLコードだけで書くことはできませんが, 固定されている部分(見出しや採点部分)はHTMLのコードで直接書くことができます(JavaScriptで生成する必要はありません)。

最後に, グローバル変数mondaiSunの値を次のように書き換えて問題数を増やせば, 当面の目標とした図9-2のような「計算プリント」が完成します。

   8  var mondaiSu = 10*2; // 問題数

このページを読み込むたびに(再読込の場合も)新しい問題が20問表示されます。

図9-2 計算プリントのページ

プログラム9-2 example09-02.html 計算問題11

まとめ

前の章で学んだ表機能とJavaScriptとを組み合わせて, JavaScriptから生成したHTMLの要素をうまく並べる方法を説明しました。

JavaScriptの構文

JavaScriptで学ぶ
文系の人にもわかるプログラミング入門
第9章 次の章へ