Copyright (C) 2000 DaiichiGakushusha Corporation. All Rights Reserved.
連載 JavaScript実習講座
エデュカーレNo.16 より
筑波大学大学院教授 久野 靖
第1回 シミュレューション
第2回 ゲーム作成
第3回 ウェブページの工夫
 <INDEX>
 これまでの連載では,プログラミング言語でさまざま なことをやってみるという方向で,ブラウザ上の JavaScript 処理系を活用してきた。この点では,ブラウ ザに組みこまれているJavaScript 処理系であっても, 非常にさまざまなことが可能だとおわかりいただけたと 思う。
 しかし考えてみれば,これは当然のことである。とい うのは,もともとコンピュータがおこなう動作はすべて プログラムによって実現されているのだから,プログラ ミング言語は「コンピュータにさせられることであれば 何でも記述できる」のが当たり前だからである。
 ただしもちろん,言語や処理系によってそれぞれ得手 不得手はある。それでは,JavaScript が得意とすること は何だろうか。JavaScript はもともと,ウェブページの 一部としてHTML に組みこみ,ページの内容をさまざ まに操作することを目的としてつくられた言語であり, それが得意分野になっている。
 今回は最終回ということで,この「JavaScript の原点」 であるウェブページの操作を取り上げ,JavaScript にそ の特徴を存分に発揮してもらうことにしよう※1
<html> ←HTML 開始
<head> ←ヘッダ(文書情報)開始
<title>sample</title> ←ページタイトル
<style> ←スタイル記述開始
…CSS による指定…
</style> ←スタイル記述終了
<script> ←JavaScript 記述開始
…JavaScript の記述…
</script> ←JavaScript 記述終了
</head> ←ヘッダ終了
<body> ←ページ本体開始
…ページ本体の記述…
</body> ←ページ本体終了
</html> ←HTML 終了
 前回まではJavaScript の学習を中心にしたため,HTML タグはほとんど使用していなかった (プログラム全体を囲む「<script>.....</script>」だけを使用していた)。しかし今回は, まずウェブページがあって,その一部をJavaScript で操作するという形になるので, もっときちんとHTML を記述する必要がある。具体的には,全体は右の形になる (個別のHTML 要素の詳細については説明しないので,適切な資料などを参照していただきたい)。
 JavaScript プログラムの動作はユーザのマウス操作 などをきっかけとして開始させる。このため,HTML 要 素の開始タグに次のような属性を指定する。
onload=”動作”
body の開始タグに記述。ページの読みこみが完了し たときに動作。初期設定に使う。
onclick=”動作”
要素上でマウスボタンがクリックされたときに動作。
onmouseover=”動作”
要素上にマウスポインタが入ったときに動作。
onmouseout=”動作”
要素上からマウスポインタが出たときに動作。
 「動作」にはJavaScript コードを記述する。onload を 除くものでは,「動作」のなかで「this」という名前を使っ てその要素を参照できる。既に学んだように,要素の背 景色はstyle.background を設定することで変更できる ので,たとえばある段落をクリックしたら色が変わるよ うにするには,次のようにしておけばよい。
<p onclick="this.style.background='pink ' ">色が変わりますよ</p>

演習1
自分が作成した適当なHTML ファイルを用 いて,その一部をクリックすると背景色が変わるよう にしてみよう。また,マウスポインタが上にくると背 景色が変わり,はずれるともとにもどるようにもして みよう。
ヒント:色名のかわりに「’none’」を設定すると,背景 色がない状態にもどる。
 ポップアップメニューとは,ユーザが何かの操作をす ると画面上にあらわれるメニューであり,そこから項目 を選択することでさまざな動作を指定するときに用いる。
 普段私たちはGUI をもつプログラムに組みこまれたメニュー機能を利用しているが,JavaScript を使うと ウェブページのなかにポップアップメニューをつくり出 すことができる。ここでは,次のような方針でメニュー をつくることにする。
・幅と高さを小さめに指定し,周囲に縁をもつ div 要素 を用意し,これをメニューボタンにする。つまりこの 要素(小さい長方形)の上にマウスがくるとメニューが あらわれる。
・メニュー本体は列が1つだけのtable(表)要素として 用意する。メニューは最初は非表示状態で,(1)の動作 の結果画面にあらわれる。また,マウスポインタがメ ニューやメニューボタンからはずれると消える。
・メニュー項目はメニューの中にあるth(表のセルない し箱)要素として用意する。セルの上にマウスポインタ がくると背景が黄色になり,はずれるともとの色にも どる。またセルの上でクリックされると,その項目が 選択される。
 メニューが選択されたときの動作はいろいろ考えられ るが,ここでは一例として,項目ごとに対応するページ にジャンプする(ブラウザの表示を切り替える)ようにし た。HTML まで含めたコードをプログラム[1]に示す。
プログラム[1]

<html><head><title>sample 1</title>
<style>
#d0 { width: 100px; height; 20px; padding: 2mm; border: solid blue 2px }
#t0 { position: absolute; width: 100px; visibility: hidden }
table { background: pink }
</style>
<script>
var tbl, num;
var dest = ['http://www.louvre.fr','http://www.nhk.or.jp',
	    'http://www.jaxa.jp'];
function init(){ tbl = document.getElementById('t0'); }
function show(){ tbl.style.visibility = 'visible';}
function hide(){ tbl.style.visibility ='hidden';}
function over(n){ tbl.rows[n].style.background = 'yellow'; num= n; }
function out(n){ tbl.rows[n].style.background= 'none'; }
function sel(){ location.href = dest[num]; }
</script>
</head>
<body onload= "init()">
<h1>さまざまなところへ行きます。</h1>
<div id="d0" onmouseover="show()" onmouseout="hide()">MENU
<table id="t0" border="1" onclick="sel()"><tbody>
<tr><th onmouseover="over(0)" onmouseout="out(0)">ルーブル美術館</th></tr>
<tr><th onmouseover="over(1)" onmouseout="out(1)">NHK</th></tr>
<tr><th onmouseover="over(2)" onmouseout="out(2)">JAXA</th></tr>
<tbody></table>
</div></body></html>


//(1)
// :
// :
// :
// :

//(2)
// :
// :
//(3)
//(4)
// :
//(5)
// :
//(6)












(1)メニューボタンがid="d0" のdiv要素,メニューが id="t0" のtable要素であり,CSS で必要な設定をお こなう。d0 については,幅,高さ,枠を設定する。t0 については,外側の要素とは独立に位置/大きさが決ま るようにするため,position:absolute(独立配置)を指 定し,最初は見えないようにvisibility: hidden を指 定する。あと幅と背景色も設定している。
(2)変数 tbl はtable要素のオブジェクト,num は現在選 択中の項目番号を格納する。dest は配列で,行き先と なるURL 文字列を並べた配列を格納する。
(3)init() はonload ハンドラから呼び出され,変数 tbl を初期設定する。
(4)show() とhide() はメニューボタンのonmouseover とonmouseout から呼び出され,メニューを見える状 態にしたり消したりする。それにはtbl.style.visibilty に’visible’,’hidden’を入れればよい。
(5)over() とout() は表の中の th 要素(メニュー項目と して使っている)のonmouseover,onmouseout から 呼び出され,マウスポインタが項目の上にきたりはず れたりしたときの動作をおこなう。上にきたときはそ の番号をnum に記録し,その行の背景を黄色くする。 はずれたときは色をなくす。表の各行はtbl.rows[行 番号]で参照できるので,背景色を変えるにはその style.background を適宜変更すればよい。
(6)sel() はメニュー上でマウスボタンがクリックされた ときに呼ばれ,配列dest のnum 番目のURL に飛ぶ。 それにはlocation.hrefにURL文字列を入れればよい。
 基本的にはこれまでに学んだように要素オブジェクト を操作しているのだが,要素やイベントハンドラを HTML 側で指定しているのが,これまでと違っている 点である。

演習2
ポップアップメニューでほかのページへ行く かわりに,どこかの色が変わるなど別の動作をさせて みよう。
 2番目の例題として,ページのコンテンツ(内容)を JavaScript によって変化させるものを取り上げよう。
 HTML だけでつくったページの場合,そのページの 内容は読んでいる間ずっと変化しないが,たとえば「ある 項目について,普段は簡単な内容だが,見ている人が必 要だと思ったときに補足説明を追加して表示させる」よ うな機能があると便利かもしれない。このような機能を, JavaScript を使ってつくってみよう ※2
 具体的な方針は次のようにして,コードをプログラム[2]に示す。
・通常の文章中に「解説」などのボタンを入れておき,こ れらを押すと補足説明が出てくるようにする。
・出てくるやり方としては,既にある文章に続いて挿入 されるものとする。
・出てきた文章についている「×」ボタンを押すことで消 す(もとの状態にもどす)ことができる。
プログラム[2]

<html><head><title>sample 2</title>
<style>
div { margin: 2ex; padding: lex; background: rgb(200,255,200) }
blockquote { display: none; border: green ridge 4px; margin: 0px; }
</style>
<script>
function show(id){ document.getElementById(id).style.display= 'block'; }
function hide(id){ document.getElementById(id).style.display= 'none'; }
</script>
</head>
<body>
<h1>クイズです。</h1>
<div>日本一高い山は何でしょう?<button onclick="show('a01')">解説</button>
<blockquote id="a01"><button onclick="hide('a01')">×</button>
それは富士山です。ちなみに高さは3777mです。
</blockquote></div>
<div>日本一長い川は何でしょう?<button onclick="show('a02')">解説</button>
<blockquote id="a02"><button onclick="hide('a02')">×</button>
それは信濃川です。ちなみに流域面積の広さでは利根川が一番ですね。
</blockquote></div>
</body></html>

//(1)
// : 
// : 	
// : 

//(2)
// :



//(3)
// :
// :
// :
// :
// :
// :
// :
// :

(1)補足説明はすべてblockquote要素にして,CSS で display:noneを指定することで最初は消えているよ うにしている(visibility:hidden で消した場合は消え てもその占める場所はあいた状態だが,display:none ではその要素は削除された状態になる)。また,見やす さのため枠もつけている。このほか項目をdiv要素に 対応させて,こちらも見やすさのため背景色をつけて いる。
(2)関数show(),hide()はいずれもID 名を指定して,そ の要素のstyle.displayを’block’(削除状態から通常 状態に変化して見えるようになる)/’none’(削除状態 に変化して消える)に変更する。
(3)HTML 側では,最初から見えている説明のほかに,解 説を表示させるためのボタン,解説を入れる blockquote要素,その中に入れる解説を消すための ボタンなどを用意している。それぞれについてID を 指定し,ボタンのonclickハンドラではどれを出す/消 すかをこのID で指定している。
 このように,ページ内容をうまく操作して見せ方を工夫するのは,JavaScript ならではといえるだろう。

演習3
補足説明の中にさらに解説ボタンがあって,補 足説明が出せるようにしてみよう。また,これらの多 段の補足説明を「ぜんぶ一気に」出せるボタンもつくっ てみよう。
 ディジタルカメラの普及とともに,ウェブページに写 真を入れておいて多くの人に見てもらうことが多くなった(写真の内容によってはパスワード保護して親しい人 だけに見てもらう場合もある)。
 しかし,写真1枚ごとにHTML でウェブページをつ くるのは大変だし,1ページに大きい画像を多数入れる と読みこみが非常に遅くなってしまう(ディジタルカメ ラの解像度が高くなったため,画像は大きくなりがちで ある)。また,大きい画像はブラウザ画面に入り切らず, うまく鑑賞できないこともある。あらかじめ縮小してお こうにも,見る人によってどれくらいの画面サイズで見 たいかは変わってくる。
 これらの問題を解消するために,1つのページに最初 は1枚目の写真だけが表示されていて,ボタンを押すと 2枚目,3枚目,…に差し替わるようにする。そうすれ ば,1枚ずつ順番にめくりながら見ていけばよい。また そのとき,画面サイズをどれくらいにするかも選択でき, それに応じて画像を小さく表示することで,さまざまな 画面サイズの人にストレスなく写真を見てもらえる。
 このような機能をもったページを,次の方針で用意し,コードをプログラム[3]に示す。
・画像を表示するimg 要素はJavaScript 側ではdocument. createElement(’img’)によってつくることができ,そのsrcプロパティにファイル名やURL を設 定して画像を読みこませることができる。読み終わったらこれをページに挿入することで,画像が画面にあ らわれる(それまで表示していた画像は取り除く)。
・画像を読み終わったときにimg オブジェクトの width,height プロパティを参照して画像の幅と高さ を調べることができる。これらを設定することで画面 表示時の幅と高さを設定できる。これを活用して,指 定されたサイズに納まるように表示サイズを調整する。
プログラム[3]

<html><head><title>sample 3</title>
<script type="text/javascript">
var a = ['IMG01.jpg','IMG02.jpg','IMG03.jpg','IMG04.jpg','IMG05.jpg'];
var maxsize = 600, idx = 0, img1, img, main, show;
function init(){
	show = document.getElementById('show');
	main = document.getElementById('main'); mv(0);
}
function chg(i) { maxsize = [400,600,800,1024][i]; mv(0);}
function mv(d) {
	show.innerHTML = ''; img1 = img;
	idx += d; if(idx<0) idx = 0;
	if(idx >= a.length) idx = a.length-1;
	img = document.createElement('img');
	img.onload = rs; img.src = a[idx];
}
function rs(){
	img.onload = null;
	var w = img.width,h = img.height, r = Math.min(maxsize/w,maxsize/h);
	if(r<1.0) { img.width = Math.floor(w*r); img.height = Math.floor(h*r);}
	if(img1!=null){ main.removeChild(img1);}
	main.appendChild(img);
	document.getElementById('show').innerHTML = '#'+(idx+1)+''+w+'x'+h;
}
</script>
</head>
<body onload="init()"><div><h1>写真をごらんください。</h1>
<button onclick="mv(-10)">-10</button><button onclick="mv(-1)">-1</button>
<button onclick="mv(+1)">+1</button><button onclick="mv(+10)">+10</button>
<select id="s0" onchange="chg(this.selectedIndex)"><option>400</option>
<option selected>600</option><option>800</option><option>1024</option></select>
</div><div align= "center" id="main"><span id="show"></span><br></div>
<body></html>



//(1)
// :
//(2)
// :
// :
// :
//(3)
//(4)
// :
// :
// :
// :
// :
// :
//(5)
// :
// :
// :
// :
// :
// :
// :


//(6)
//(7)
// :
//(8)
// :
//(9)


(1)画像ファイル名(何個あってもよい)は配列a に入れ ておく。また,画像の縦横の最大サイズ(maxsize),画 像番号(idx),1つ前と現在の画像(img1,img),画像 を入れるHTML 要素と説明を入れるHTML 要素 (main,show)を変数として用意しておく。
(2)ページが最初に表示されたときにはinit()が呼ばれ るようになっている。ここでshowとmain 要素のオ ブジェクトを取り出し,またmv(0)で最初の画像を表 示させる。
(3)選択メニューが変化したときはchg()が呼ばれ,引数 として選択した番号が渡されるので,対応する最大サ イズをmaxsizeに入れ,mv(0)で画像を表示し直す。
(4)関数mv()は画像の表示,再表示をすべておこなう。 引数は「画像番号をいくつ進める/もどすか」を意味す るが,0のときは再表示ということになる。まず説明 文をクリアし,現在の画像を変数img1に入れ,次の画 像の画像番号を計算する(0〜a.length-1の範囲をはず れたら範囲に入るように修正する)。続いて新しい img 要素をつくり,画像を読みこみ終わったら関数rs ()が呼ばれるように設定してから,srcプロパティに 画像ファイル名を入れることで読みこみを開始させる。
(5)読みこみ時の動作をクリアしてから(重複して呼ばれ ないため),画像の幅と高さを取得し,最大サイズに対 する比率を計算して1.0未満なら幅と高さを最大サイ ズで納まるように設定する。続いて,1つ前の画像が あれば(img1がnullでなければ)main 要素からそれ を削除し,main 要素の末尾に新しい画像を追加する。またshow要素の内容として説明文字列を入れる。
(6)HTML 側では,bodyの開始タグでロード時にinit() を呼ぶようにする。
(7)画像送りボタンは±1のほかに,枚数が多い場合にそ なえて±10ずつ送るボタンも用意した。これらがクリ ックされたときは適切な引数を指定してmv()を呼ぶ。
(8)select メニューは,選択が変化したときは番号をもっ てchg()を呼ぶ。
(9)最後にID 名としてmain をもつdiv要素,その中に ID 名としてshowをもつspan 要素が置かれている。
 このように,重たくなりがちな画像もJavaScriptでう まく制御することで,それなりの画像ビューアのような ページをつくることができるとわかる※3

演習4
2枚の写真を見くらべたいという要望もある かもしれない。2つの画像を並べて表示し,それぞれ 前後にめくれるようなページをつくってみよう。
 JavaScript はプログラミング入門用の言語としても 活用できるが,ブラウザのもつ機能と組み合わせること で多様なプログラムをつくれることがおわかりいただけ たと思う。さらに,プログラムをウェブページに組みこ むため簡単に他人にも公開できるので,生徒の作品を公 開して意見や感想をもらうなどの方向も考えてみていた だきたい。