Copyright (C) 2000 DaiichiGakushusha Corporation. All Rights Reserved.
連載 JavaScript入門講座
第3回 ウェブページに動きをつける
エデュカーレNo.12 より
筑波大学大学院教授 久野 靖
今回は,JavaScriptを使ってウェブページをさまざまに動かします。
第1回 基本的なプログラム
第2回 アルゴリズムの学習
第3回 ウェブページに動きをつける
 <INDEX>
 連載の第1回で説明したように,JavaScriptはもともと,ウェブページの中にHTMLと一緒に組みこんで,さまざまな動作をつけるための言語としてつくられたものである。
 通常のウェブページは,サーバから取り寄せられて一度表示されると,あとは変化することがない。プラグイン*1の追加によって,長方形の領域や1つのページを別のプログラムに割り当て,領域内部の表示をそのプログラムにまかせる方法はあるが,これだと動くのはその領域の内側だけであり,また特別なプログラムを作成するためのソフトウェアや技術が必要になる。
 これに対し,JavaScriptを使うと,ウェブページを構成するHTMLのさまざまな要素をJavaScriptプログラムから参照し,その色,位置,その他の動作を変更することができる。そして,JavaScriptプログラムを入力するのは前回までと同様,メモ帳などのエディタを使えばよい(今回はプログラムが操作するHTMLも一緒に入力する)。
 ウェブページをJavaScriptで操作する場合は,ウェブページのHTMLを自分で作成し,どの部分がどのようなHTMLの要素で構成されているか把握しておくのが基本となる。そこで,HTMLの書き方について最低限必要なことをまとめておくことにする。
 HTMLは,タグとよばれる「しるし」でページのさまざまな内容部分を囲むようにして構成されている。タグと内容部分を合わせたものをHTMLの「要素(エレメント)」とよび,一般に次のような形をしている。
     <タグ名 追加指定 …>内容部分……</タグ名>  

HTMLの要素
 HTMLの要素は,先に説明したように,開始タグがあり,内容部分があり,最後に終了タグがあるという形をしている。内容部分には普通の文字が入ることもあるし,また別のHTML要素が入ることもある。簡単なHTMLファイルの例で見てみよう。

<html>
<head><title>サンプル1</title></head>
<body id="hon1">
<h1 id="mid1">これはサンプルです。</h1>
<p id="dan1">私たちはJavaScriptを使って,ページの内容を動かしてみようと思っています。</p>
</body>
</html>

 この例では,それぞれ次のような内容をあらわすHTML要素が用いられている。
<html>…</html>HTMLファイル全体
<head>…</head>文書に関する情報
<title>…</title>ページのタイトル
<body>…</body>ページの本体(ブラウザのウィンドウの中に表示される)部分
<h1>…</h1>大見出し
<p>…</p>段落(パラグラフ)

 この例では,本体,大見出し,段落の3つについては,追加指定として「id="識別名"」という形のものがつけてある。識別名は,重複がないように注意してつける。JavaScript側では,この識別名(ID:identifier)をもちいて「どの要素」ということを指定し,指定した要素をさまざまに操作できる。
 JavaScript側でHTML要素を操作するには,
変数 = document.getElementById('識別名')

のようにして,IDを指定して,要素をあらわすオブジェクト(データ構造)を変数に取得してくる。そのあと,その要素を操作する方法として,表1のような機能を使うことができる。

色を指定するとき
 HTMLで使われる「#xxxxxx」形式(16進数6桁)か,または「rgb(赤,緑,青)」という形で指定する(赤,緑,青のところに0〜255までの整数を指定する)。
表1 JavaScriptからHTML要素を操作する
文字列の変更要素.innerHTML = '文字列'
背景色の変更要素.style.backgroundColor = '色'
見えなくする要素.style.visibility = 'hidden'
見えるように要素.style.visibility = 'visible'
相対位置指定可要素.style.position = 'relative'
絶対位置指定可要素.style.position = 'absolute'
横方向位置指定要素.style.left = '数値px'
縦方向位置指定要素.style.top = '数値px'
文字色の変更要素.style.color = '色'
枠をつける要素.style.border = 'solid 色 幅px'
二重枠をつける要素.style.border = 'double 色 幅px'
立体枠をつける要素.style.border = 'ridge 色 幅px'
枠を消す要素.style.border = 'none'

位置や幅や長さなどを指定するとき
 必ず単位を指定する。表1では「px」(ピクセル:画面上の点の数)を単位としていたが,「mm」「cm」などの長さを指定したり,「%」をつけて画面やページ全体の幅や高さに対する比率を指定することもできる。

<html>
<head><title>サンプル1</title></head>
<body id="hon1">
<h1 id="mid1">これはサンプルです。</h1>
<p id="dan1">私たちはJavaScriptを使って,ページの内容を動かしてみようと思っています。</p>
<script>
x = document.getElementById('hon1');
r = Math.floor(Math.random() * 256);
x.style.backgroundColor = 'rgb(' + r + ',255,100)';
</script>
</body>
</html>
結果画面(プログラムを実行するたびに,背景の色が変化する。)
 ではいよいよ,JavaScriptを使ってページ内容を変更してみよう。プログラム1では,ページを読みこむときに乱数*2を使って背景の色をランダムに変更する。
 JavaScriptのプログラムはこれまでと同じように<script>…</script>の内側に書くが,今回は必ず終わり近く,具体的には</body>の直前に書くようにする。というのは,IDを指定して要素を参照するためには,そのIDが既に定義されている必要があるので,IDを定義するHTMLを先に置かなければならないからである。
 さて,JavaScriptプログラムの1行目では
x = document.getElementById('hon1');

により,本体(<body>…</body>)に対応する要素オブジェクトを変数xに取り出してくる。次に,
r = Math.floor(Math.random() * 256);

により,0〜255までの整数の乱数を計算し,変数rに入れる。Math.random()は0以上1未満の一様乱数*3を計算する機能であり,それを256倍することで0以上256未満の乱数を求め,Math.floor()という切捨て機能を用いて整数になおしている。
 最後に,この値をもとに要素xの背景色を設定する。
x.style.backgroundColor = 'rgb(' + r + ',255,100)';

 ここでは,「rgb(乱数,255,100)」という文字列を文字列連結によって組み立てている。これで,ページを表示しなおすたびに微妙に色合いが変化するページがつくることができる。

演習
 プログラム1では赤の成分だけを乱数で計算していたが,ほかの成分も乱数で計算してみよう。また,本体の背景以外に,見出しや段落の背景や,これらの文字の色なども別の乱数で計算してみよう。
 ここまでに学んだJavaScriptプログラムでは,<script>…</script>の内側に書かれた命令を順に実行することが基本になっていた。しかし,「マウスがクリックされたら〜する」「一定時間ごとに〜する」などの動作をさせるには,「〜」の部分を「ひとまとまりの動作」としてまとめて指定できなければならない。
 JavaScriptでは,このようなひとまとまりの動作に名前をつけたものを「関数」とよび,次の形で定義する。
function 関数名() { 動作… }

 ここで「動作…」の部分にはいくつでもJavaScriptの命令を書くことができる。
 一定の短い時間間隔ごとに,徐々に位置を変えたり色を変えたりすることで,ウェブページにアニメーションの効果をもたせることができる。そのためには,次のようにsetInterval()という機能を使う。
 setInterval(関数名, ミリ秒数);

 ここで「関数名」は,一定間隔で実行する動作を先で説明したように関数として定義し,その名前を指定する。(後ろに「()」をつけてはいけないので注意)。ミリ秒数は,何ミリ秒間隔で指定した関数を実行するかを指定する。なお,setInterval()の親戚として,指定した時間後に1回だけ動作を実行させる関数setTimeout()もある。
  setTimeout(関数名, ミリ秒数);


<html>
<head><title>サンプル2</title></head>
<body id="hon1">
<h1 id="mid1">これはサンプルです。</h1>
<p id="dan1">私たちはJavaScriptを使って,ページの内容を動かしてみようと思っています。</p>
<script>
e = document.getElementById('mid1');
e.style.position = 'absolute';
y = 0; r = 0;
function act() {
	y = (y + 3) % 400; r = (r + 1) % 256;
	e.style.top = y + 'px';
	e.style.backgroundColor = 'rgb(' + r + ',255,100)';
}
setInterval(act, 20);
</script>
</body>
</html>
結果画面(見出しの色と位置が変化する。)
 今度は,ページ本体ではなく見出しのIDを指定して変数eに要素オブジェクトを取り出す。そして,位置指定を'absolute'(絶対位置指定)に設定することで,動かす準備をする。絶対位置指定とすると,その要素はページのほかの内容とはまったく独立したものとして任意の場所に置けるようになる。
 次に,縦方向の位置と,色の赤成分とを徐々に変化させるため,これらの現在値を変数yrに入れることにして最初は0として初期設定しておく。
 次に,繰り返し実行させる部分をactという名前の関数として定義する。その中では,yは3ずつ,rは1ずつ増やすが,ただしそれぞれ400と256で剰余を取っているので,これらの値以上になることはない。その後,縦位置と色を設定する。
 以上で関数が定義できたので,最後にこの関数を20ミリ秒間隔で実行するようにsetInterval()を呼び出す。

演習
 縦方向だけでなく,横方向にも動くようにしてみよう。また,一定のペースで動くのでなく,速さが変化したり,動く向きが変わったりするように工夫してみよう。複数の要素をそれぞれ独立に動かしてみてもよい。
 ページ内容を動かすとき,ユーザの操作と関係なく動き続けるだけではあまりおもしろくない。JavaScriptでは,ユーザがマウスポインタを動かして文字などの上に来た時やクリックした時に動作を実行させることもできる。それには表2のような機能を使う。
 このような、外部の操作に応じておこなう動作のことを,一般に「イベントハンドラ」とよぶ。
表2 ユーザ操作への応答の設定
マウスがのった要素.onmouseover = 関数名
マウスが外れた要素.onmouseout = 関数名
クリックされた要素.onclick = 関数名
キーが押された要素.onkeydown = 関数名

<html>
<head><title>サンプル3</title></head>
<body id="hon1">
<h1 id="mid1">クリックしてみて!</h1>
<p id="dan1">私たちはJavaScriptを使って,ページの内容を動かしてみようと思っています。</p>
<script>
e = document.getElementById('mid1');
e.style.position = 'absolute'; e.style.top = '20px'
e.style.border = 'solid blue 4px';
function modosu() { e.innerHTML = 'クリックしてみて!'; }
function act() {
	x = Math.floor(Math.random()*400);
	y = Math.floor(Math.random()*400);
	e.style.left = x + 'px'; e.style.top = y + 'px';
	e.innerHTML = 'おっと!';
	setTimeout(modosu, 1500);
}
e.onmouseover = act;
</script>
</body>
</html>
結果画面(「クリックしてみて」にマウスを近づけると…,文字が「おっと!」と言って逃げる。)
 今度は,ユーザが見出しの上のマウスポインタをもって行くと逃げる,という動作をさせてみよう。
 見出しを動かせるように用意するのは先の例と同じだが,今度は範囲が分かりやすいように青い枠もつけておく。そして,見出しの文字列を変更するので,後でもとにもどすという動作をmodosuという名前の関数として定義する。一方,actという関数は最後の行で,その上にマウスがのった時に実行されるように設定する。
 マウスがのった時の動作は,xyに0〜400の範囲の乱数を計算してその位置に見出しを動かし,中の文字列を「おっと!」に変更する。そのままだとつまらないので,1500ミリ秒後にmodosuをよんでもとにもどすようにしている。

演習
 別の場所で「カウントダウン」と「回数表示」をおこない,30秒間で何回文字列をキャッチできるかを競うゲームにしてみよう。30秒たったら,10秒間待機して,再度はじまるようにするとよい。
 JavaScriptはブラウザに組みこまれているため,どこでも手軽にプログラミングの実習ができ,アルゴリズムの学習などにも適している。また,それだけでなく,HTMLの要素を制御することでゲームのような楽しいプログラミングにも使えることがお分かりいただけたと思う。生徒に「プログラミングの楽しさ」を味わってもらうような授業を,ぜひ工夫してみていただきたい。