Post on 07-Oct-2020
transcript
高大連携アドバンストプログラム
JavaScript事前学習資料
立命館大学 情報理工学部
2012年 4月 24日
目次
1 はじめに 3
2 JavaScript 3
2.1 JavaScriptの概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 JavaScriptの埋め込み . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3 JavaScriptの実行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.4 関数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.5 変数と値 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.6 関数の実行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.7 繰り返し文 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.8 関数の組み合わせ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.9 条件文 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.10 関数を他の関数に引数として渡す . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.11 複雑な計算 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3 HTML文書の操作 12
3.1 ボタン . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.2 HTML要素の書き換え . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.3 ユーザの入力 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4 タイマーとその応用 18
4.1 タイマー関数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.2 時間をおいた繰り返し . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
5 放物運動の簡易アニメーション表示 20
5.1 物体の表示 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
5.2 表示位置の指定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1
5.3 移動の簡易アニメーション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
5.4 放物運動の表現 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
5.5 重力加速度の切り替え . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
5.6 軌跡の表現 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
付録 A JavaScript実験環境 (JSWorkbench) 34
付録 B Firefox のダウンロード・インストール 36
付録 C Firefoxのエラーコンソール 40
C.1 エラーコンソールの表示の仕方 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
C.2 JavaScriptの課題をプログラム中に表示されるエラー通知の例 . . . . . . . . . . . . 41
2
1 はじめに
この学習資料は JavaScriptの事前学習資料です.前半では,JavaScriptを使用した基本的なプロ
グラミングの説明をします.後半では,高校物理で学ぶ放物運動の簡単なアニメーションを実現する
ことを目標にして,JavaScriptの応用例を説明します.
2 JavaScript
2.1 JavaScriptの概要
JavaScript はWeb ブラウザ上でよく利用されるプログラミング言語です.JavaScript を用いる
ことで,ユーザのマウス操作やキーボード入力に応じて表示内容が切り替わるインタラクティブな
Webページを作ることができます.
JavaScript のプログラムは HTML 文書の中で特定のタグに挟んで埋め込むだけで実行されま
す.プログラムはWebブラウザによって実行され,ユーザのマウス操作やキーボード入力に応じて
HTMLの内容が書き換えられます.本資料では JavaScript の基本的な部分だけを述べますが,音楽
の再生,サーバとの通信に至るまで,JavaScriptで実現可能な機能は多岐にわたります.
なお,付録に本学習資料における推奨実行環境について記述していますので,JavaScriptを初めて
学習する人は参考にしてください.
2.2 JavaScriptの埋め込み
JavaScriptは次のように HTML文書に埋め込むことができます.<script>と</script>タグで
プログラムを囲み,HTML文書に埋め込みます.プログラムにはブラウザに描画をする命令や計算
をさせる関数などを組み合わせたものを記述します.ただし,//で始まる箇所はプログラムの実行に
影響を与えず,無視されます.このような箇所をコメントと呼びます.
<html><head></head><body><script type="text/javascript">// ここに「プログラム」を書く</script></body></html>
2.3 JavaScriptの実行
JavaScriptを埋め込んだ HTML文書を実行させる必要があります.実行するためには,Webブラ
ウザで HTML文書を開く必要があります.以下の内容のテキストファイルを作成し,hello.html
という名前で保存してください (ファイル名は好きな名前でも構いません).そして,そのファイルを
Webブラウザで開いてください.
<html><head></head>
3
<body><script type="text/javascript">// Helloの文字列を出力する.document.write(’Hello’);</script></body></html>
プログラムを実行した結果をWebブラウザの画面に出力するには,document.writeという「関
数」を利用します.関数の詳細は 2.4で説明しますが,「関数名」と「引数」に分かれます.引数は
()で囲まれた部分で,引数を利用することで関数に値を渡すことができるようになります.上記プ
ログラムでは,関数名は document.writeで,引数は’Hello’になります.(’の代わりに"を使用
して,"Hello"を引数として渡しても同じことになります.)
この関数は引数に指定したものをブラウザの画面に表示する機能を持つ関数です.引数には表示さ
せたい数値,変数,文字列などが指定できます.複数指定する場合は カンマ (,)で区切ります.
[練習問題 1] Webブラウザ上に自分の名前を表示するプログラムを作成しなさい.
以降,基本的な命令や関数について説明します.
2.4 関数
JavaScript では「関数 (function)」を定義することができます.数学で学ぶ関数とよく似たもの
です.JavaScript の関数は「引数」として値を渡すと,計算の結果を「返り値」として返します.
JavaScriptでプログラムを書くことは関数を定義していくことと考えることもできます.
簡単な例として,数学における一次関数を JavaScriptの関数で表現してみましょう.例えば,
y = 3x+ 4
の一次関数があるとします.これを xの関数 func(x)
y = func(x) = 3x+ 4
として考えます.JavaScriptのプログラムで表現すると次のようになります.
function func(x) {return 3 * x + 4;
}
ここで,func は関数の名前を表します.return は,関数の返り値を示します.四則演算の書き方
は,JavaScriptでは次のように書きます.
足し算: 5 + 3
引き算: 9 - 3
掛け算: 3 * 8
割り算: 6 / 2
剰余: 7 % 3 (7を 3で割った時の余りが得られます.つまり,1になります)
4
掛け算と割り算の文字が数学の書き方を異なりますので注意してください.また,余りを求めるた
めの式も利用できます.さらに,丸括弧を使うことで四則演算の順序を指定することもできます.
関数を呼び出すときは関数の名前を使って呼び出します.例えば,func(1)により,引数として 1
を渡した時の結果を求めることができます.この例では (xに 1を代入すると 3 ∗ 1 + 4 = 7なので)
func(1)の値は 7になります.
[練習問題 2] 3で割った時の余りを求める関数 (仮に mod3と名付けます)を定義しなさい.
(ヒント) mod3の関数は以下のような定義になります.
function mod3(x) {return (ここにxを 3で割った余りを求める式を書く) ;
}
2.5 変数と値
変数とは,値に関連付けられる名前です.変数に値を代入するといった言い方をします.代入する
際に=を利用しますが,=は数学における「等しい」というより,「格納する」という命令と捉えるこ
とができます.ただし,変数を最初に使用するときには,varという単語を,変数の前につける必要
があります.また,変数の名前は好きな名前を付けることができ,複数の英数字から構成されていて
も問題ありません.
以下に,変数 iに 3を代入する例を示します.
var i = 3;
さらに変数の値を別の変数に代入したり,計算の結果を変数に格納することもできます.
var x = 2;var y = x;var z = x + 1;
この例では,変数 yには,変数 xに入っていた値,すなわち 2が入ります.また,変数 zには,変数
xに入っていた値 (2)に 1を足した 3が入ることになります.
変数には整数や小数といった値だけではなく,文字列も代入できます.文字列とは,その名の通
り,文字の並びのことです.単一引用符 (’)もしくは二重引用符 (")で囲む必要があります.以下に
文字列の例を示します.文字列を使うことで,ユーザにわかりやすく表示させることができるように
なります.利用例は次の 2.6で説明します.
var string1 = "Hello";var string2 = ’こんにちは’;
2.6 関数の実行
では,プログラムを実行して動作を確認してみましょう.確認するためには関数の結果を Web
ブラウザに表示させる必要があります.すでに説明したように,document.write という関数を
5
利用します.引数に,変数を指定した場合,その変数に代入されている値が表示されます.なお,
document.write の関数は複数の引数をとることができ,引数として渡された値をすべて表示し
ます.
以下の内容のファイルを作成し,Webブラウザで開いてください.
<html><head></head><body><script type="text/javascript">// 関数funcの定義function func(x) {return 3 * x + 4;
}
// 変数resultに関数の引数として 1を与えた時の結果を入れるvar result = func(1);
// 変数resultの値を出力する.document.write(’func(1) = ’, result);</script></body></html>
Webブラウザには func(1) = 7と表示されます.func(1)の 1を別の数値に書き換えてファイ
ルを上書き保存し,Webブラウザで再読込みすれば,その数値で計算した結果が表示されます.1を
2, 3といった数値に変えたときにどのような表示になるか確認してください.
[練習問題 3] 次の xの2次関数を JavaScriptで表現しなさい.また,関数の引数として 2を与え
た時の値を出力しなさい.関数の名前は自由に決めて構いません.
y = 3x2 + 4x+ 5
[練習問題 4] 練習問題 2 で定義した mod3 関数を用いて,101 を 3 で割った時の余りを出力しな
さい.
2.7 繰り返し文
上記で定義した関数 (func)を用いて,引数を 1 から 10 まで 1ずつ変えて計算させるためには,
引数の数値を直接修正して,そのたびにWebブラウザで再読込みする必要がありました.同じ計算
を繰り返しすための便利な書き方があります.for文と呼ばれる繰り返しのための命令です.for文
では
for (カウンタ=初期値; カウンタ継続条件; 次のカウンタ値) {繰り返したい関数や命令
}
という文を用いることで,任意の命令を指定回数繰り返す事ができます.さらに,指定回数繰り返す
のみならずカウンタの継続条件が満たされる間,中括弧{ }内の命令を繰り返す事ができます.
6
上記で定義した関数 (func)を用いて,引数を 1 から 10 まで 1ずつ変えた時の値を出力するプロ
グラムは,forを使って次のように定義できます.
// 関数funcの定義function func(x) {return 3 * x + 4;
}
// 繰り返し用の変数を宣言するvar x;for (x = 1; x <= 10; x = x + 1) {var result = func(x);document.write(’func(’, x, ’) = ’, result, ’<br>’);
}
このプログラムの動作を確認してください.ここで<br>は強制改行を意味する HTMLのタグです.
繰り返しの中で xが一つ増えるごとに改行されることになります.
[練習問題 5] 練習問題 3 で定義した2次関数を用いて,引数として 0から 9まで 1 ずつ順に変え
た時の値を出力しなさい.
2.8 関数の組み合わせ
JavaScriptの関数は数学の関数とは異なり,必ずしも値を返す必要はありません.また,値を出力
するなどの「副作用」を起こすことができます.既に出てきた document.writeも副作用を起こす
関数の一つです.
上記のプログラム例では,関数 func は引数として渡された値から計算結果を値として返すも
のでした.ここでは計算した結果を出力する機能をもった関数を定義してみます.関数の名前を
funcWriteとすると例えば次のように定義できます.
// 関数funcの定義function func(x) {return 3 * x + 4;
}
// 関数funcの計算結果を表示する関数を定義するfunction funcWrite(x) {var result = func(x);document.write(’func(’, x, ’) = ’, result, ’<br>’);
}
ここで定義した funcWrite関数を使用すると,1から 10まで順に引数の値を変えた時の結果を出
力するには,次のようになります.
// 関数funcの定義function func(x) {return 3 * x + 4;
}
// 関数funcの計算結果を表示する関数として定義する
7
function funcWrite(x) {var result = func(x);document.write(’func(’, x, ’) = ’, result, ’<br>’);
}
// 繰り返しの変数を宣言する.var x;for (x = 1; x <= 10; x = x + 1) {funcWrite(x);
}
[練習問題 6] 練習問題 3 で定義した2次関数について,同様に結果を出力する関数を定義して,そ
の上で,引数として,0から 9まで 1 ずつ順に変えた時の値を出力しなさい.
2.9 条件文
次に自然数 nの階乗 (n!)を求める関数を定義してみましょう.nの階乗は,1から nまでの自然
数をかけ合わせたもので,以下のように書けます.
n! = n× (n− 1)× · · · × 2× 1
階乗は nを引数として与えた時に,n!の値を返す関数として考えることができます.自分自身を呼
び出す再帰的な適用を使って次のような関数として定義することができます.
factorial(n) =
{1 (n = 1の場合)n ∗ factorial(n− 1) (それ以外の場合)
このように,条件に従い計算式を変えたい場合があります.nが,1の場合は関数の結果として 1
を返し,そうでない場合は,n * factorial(n - 1)を計算し,その結果を返します.条件を加え
た式を JavaScriptの関数で定義すると次のようになります.
function factorial(n) {if (n <= 1) {return 1;
} else {return n * factorial(n - 1);
}}
数学的な階乗の定義では,引数として自然数が渡されることが前提になっていますが,プログラムで
は 1未満の数が引数として渡されても無限ループにならないように ifの中では 1以下か否かを判定
しています.関数 factorialの定義にあるように関数の中で自分自身を呼び出すことも可能です.
この関数の定義の中に現れる条件式は if文と呼び,
if (条件) {関数や命令
} else {関数や命令
}
8
の形式で書きます.条件には
a < b // a は b より小さいa <= b // a は b より小さいか等しいa > b // a は b より大きいa >= b // a は b より大きいか等しいa == b // a は b と等しいa != b // a は b と異なる
のような記述ができます.aや bは変数や数値になります.if文は,条件が正しいとき,直後の関
数や命令を実行し,そうでなければ elseの直後の関数や命令を実行します.
[練習問題 7] n番目のフィボナッチ数を fibn とすると次の式で定義されます.
fib0 = 0
fib1 = 1
fibn = fibn−1 + fibn−2 (n >= 2の場合)
これを nを引数としてとり,n番目のフィボナッチ数を返す関数 (fib) として定義しなさい.さ
らに,20番目までのフィボナッチ数を出力しなさい.
(ヒント) n番目のフィボナッチ数を返す関数 (fib)は例えば,以下のように定義できます.
function fib(n) {if (n <= 0) {return 0;
} else if (n == 1) {return 1;
} else {return fib(n - 1) + fib(n - 2);
}}
2.10 関数を他の関数に引数として渡す
これまでの例では for を用いて繰り返しを書いていました.ここでは,繰り返して実行を行う関
数を定義してみることにします.関数の引数として,繰り返しの中で実行される処理を定義した関
数,繰り返しの初期値,最終値を渡すものとします.このような関数 (repeat)の定義例を以下に示
します.
function repeat(f, start, end) {var i;for(i = start; i <= end; i = i + 1) {f(i);
}}
ここで for文中の f(i)は,repeat関数の引数として渡された関数 (fの値になっています)に iの
値を引数として渡して呼び出すことを表しています.
上記の repeat関数を使用して,前節の例を書き直すと以下のようになります.
9
// 関数funcの定義function func(x) {return 3 * x + 4;
}
// 関数funcの計算結果を表示する関数として定義するfunction funcWrite(x) {var result = func(x);document.write(’func(’, x, ’) = ’, result, ’<br>’);
}
function repeat(f, start, end) {var i;for(i = start; i <= end; i = i + 1) {f(i);
}}
// 実行するrepeat(funcWrite, 1, 10);
[練習問題 8] 練習問題 6の解答を上記で定義した repeat関数を用いて作成しなさい.
2.11 複雑な計算
いままで作成してきた関数,for文,if文を組み合わせて,ライプニッツの公式を用いた円周率
の値 (3.1415926…)を求めるプログラムを作成してみましょう.
π = 4(1− 1
3+
1
5− 1
7+
1
9− · · ·)
上記のライプニッツの公式は,円周率を繰り返し計算で表すための有名な公式です.右辺の加算す
る項を無限に長くすると,左辺(円周率の値)に収束します.ライプニッツの公式は収束が遅く,加
算回数をかなり増やさないと円周率の値が求まりませんが,円周率を求める基本的な公式の一つとし
て知られています.こういった,計算の繰り返しによる円周率計算は,コンピュータ上で円周率の値
そのものを計算する他,コンピュータの性能を測るのにも用いられます.(皆さんも,円周率が×兆
×億桁まで求められた,というニュースを聞いたことがあるでしょう)
具体的にプログラムを作っていきます.ある nに対して,ライプニッツの公式の第 n項までの加算
で得られる関数を S(n)とします.nを充分大きくすることで,円周率の近似値が得られます.ライ
プニッツの公式は次のように変形できます.
S(n) = 4− 4
3+
4
5− 4
7+
4
9− · · · 4
2n− 1
=
n∑i=1
sig(i)4
2i− 1
10
ここで,
sig(i) =
{1 (iが奇数の場合)−1 (iが偶数の場合)
上式の Σ記号の中身を繰り返し加算して S(n)を求めるプログラムは次の様に書けます.
function S(n) {var Sn = 0;var i;for (i = 1; i <= n; i++) {Sn = Sn + sig(i) * 4 / (2 * i - 1);
}return Sn;
}
function sig(i) {if (i % 2 == 1) {return 1;
} else {return -1;
}}
関数 S の 1 行目では,S(n) の値を表す変数 Sn を 0 に初期化します.以降で,この Sn にライプ
ニッツの公式の右辺の各項を繰り返し加算していきます.カウンタ iが 1から nになるまで,for文
で繰り返し計算を行っています.カウンタ iは Σ記号の添え字に当たる変数です.for文の中では,
関数 sigを呼び出しています.関数 sigの if文は,iを 2で割った余りが 1になるという条件が成
立した場合は 1を,そうでない場合は −1を返します.その後,
Sn = Sn + sig(i) * 4 / (2 * i - 1);
という式で Σの計算をしていきます.これは,「現在の」Snの値と sig(i) * 4 / (2 * i - 1) の
和を変数 Snに格納することを意味します.
最後に,document.write(S(100000))として関数 Sを呼び出して,その結果を表示してみましょ
う.繰り返しの回数である 100000を小さい値やもっと大きな値で試してみて,結果がどう変わるか
見てみましょう.
[練習問題 9] ライプニッツの公式を用いて πを計算する時の繰り返す回数を 10i として iを 1から
5まで 1ずつ変化させた時に精度がどのように変わるか表示するプログラムを作成しなさい.(参
考:10i は JavaScriptでは,Math.pow(10, i)でも計算することができます)
11
3 HTML文書の操作
以下では,JavaScriptの応用として,動きがあるWebページの作成に挑戦します.特に放物運動
の簡単なアニメーション表示の実現を目標に説明します.
3.1 ボタン
HTML文書中にボタンを設け,ボタンをクリックした時に動作を行うプログラムを作成してみま
す.ボタンは buttonタグを用いて作成します.以下は,「クリック」というラベルがついたボタン
の例です.
<button>クリック</button>
ボタンをクリックした時に動作するプログラムは button タグの onclick 属性で指定できます.
以下の例は,ボタンをクリックすると,ポップアップウィンドウが現れ,Helloという文字が表示さ
れるものです.
<button onclick="alert(’Hello’)">クリック</button>
ここで,alertは引数の文字列をポップアップウィンドウに表示する関数で,JavaScriptに用意され
ているものです.buttonタグの属性の値を表わすために"の文字を使用しているため,alert関数
の引数は’で囲んでいることに注意してください.
[練習問題 10] ボタンをクリックすると,「こんにちは」の文字がポップアップウィンドウに表示さ
れるプログラムを作成しなさい.
以下に解答例を示します.
<html><head><title>ボタンの例</title></head><body><button onclick="alert(’こんにちは’)">クリック</button></body></html>
上記の例では,alert関数を呼び出しましたが,自分で定義した関数を呼び出すこともできます.
次の例をみてください.
<html><head><title>ボタンの例</title><script type="text/javascript">function greet(x) {alert("こんにちは," + x + "さん");
}</script></head>
12
<body><button onclick="greet(’一郎’)">挨拶</button></body></html>
「挨拶」と書かれたボタンをクリックすると,「こんにちは,一郎さん」と書かれたポップアップ
ウィンドウが表示されることを確認してください.
[練習問題 11] ボタンをクリックするとポップアップウィンドウに円周率 (π)の値を表示するプロ
グラムを作成しなさい.円周率の値は前節で説明したライプニッツの公式を用いて計算しなさい.
3.2 HTML要素の書き換え
これまでの例では,JavaScriptの出力結果を document.writeを使用して出力したり,alert関
数を使用して,ポップアップウィンドウに表示させたりしていました.ここでは,JavaScript から
HTML文書の内容を書き換える方法を説明します.
例として次のような HTML文書を取り上げます.
<html><head><title>spanタグの利用</title></head><body><p>出力:<span id="output">ここを書き換えます</span></p></body></html>
ここで,pは段落を示すタグです.また,spanは場所を指定するのに用いられるタグです.span要
素はインライン要素と呼ばれるものの一つで,前後に改行が入らず,文章の一部に含めることができ
ます.この例では,「出力:」で始まる文章の一部を示しています.また,spanタグの id属性とし
て outputが指定されています.JavaScriptのプログラムからは,id属性のもとにこの span要素
にアクセスします.
JavaScriptから span要素の内容を書き換える例を以下に示します.
<html><head><title>spanタグの利用</title><script type="text/javascript">function test() {var output = document.getElementById("output");output.innerHTML = "こんにちは";
}</script></head><body><button onclick="test()">クリック</button><p>出力:<span id="output">ここが書き換わります</span></p></body></html>
13
この例では,ボタンをクリックすると,test関数が実行され,「ここが書き換わります」とあるとこ
ろが,「こんにちは」に書き換わります.
test関数の中を見てみましょう.まず,document.getElementByIdの関数を用いて,id属性が
outputの HTML要素を求めます.この例では,span要素が求められます.求められた要素は変数
outに代入され,out.innerHTMLに値を設定することで,span要素の内部を書き換えることができ
ます.この例では,test関数を実行すると,以下と同様の HTML文書になります.
<p>出力:<span id="output">こんにちは</span></p>
innerHTMLに代入する値には,HTMLのタグを含めることもできます.例えば,上記の例で
var output = document.getElementById("output");output.innerHTML = "<b>出力結果</b>";
に変更すると,出力結果を強調表示にすることができます.
[練習問題 12] ボタンをクリックすると円周率 (π)を計算して,ブラウザのウィンドウ中に表示す
るプログラムを作成しなさい.円周率の値は前節で説明したライプニッツの公式を用いて計算し
なさい.
3.3 ユーザの入力
3.3.1 テキストの入力
HTMLには,ユーザが値を入力するための inputタグが用意されています.ここでは,inputタ
グを用いてユーザからの入力を受け取る方法を説明します.
以下の HTML 文書では,入力エリアと表示された横にテキストを入力するボックスが表示され
ます.
<html><head><title>inputの例</title></head><body><p>入力エリア: <input type="text" id="input" /></p></body></html>
inputタグの type属性に textを指定することによりテキストを入力することができるようになり
ます.type属性には textの他に checkboxなどが指定できます.
JavaScriptプログラムから入力エリアに入力された文字列を取得するためには,id属性の値をも
とに対象とする input要素を求め,その value属性の値を求めます.具体例を以下に示します.
<html><head><title>inputの例</title><script type="text/javascript">function test() {var input = document.getElementById("input");
14
// input要素に入力された値を取り出すvar text = input.value;var output = document.getElementById("output");output.innerHTML = text;
}</script></head><body><p><button onclick="test()">コピー</button></p><p>入力エリア: <input type="text" id="input" /></p><p>出力エリア: <span id="output"></span></p></body></html>
このプログラムでは,コピーというボタンが表示され,このボタンをクリックすると入力エリアに入
力された文字列が出力エリアに表示されます.
[練習問題 13] 名前を入力するエリアを設け,ボタンをクリックすると,「こんにちは,~さん」(~
には入力された名前が入る)と表示するプログラムを作成しなさい.
以下に解答例を載せます.
<html><head><title>inputの応用</title><script type="text/javascript">function greet() {var input = document.getElementById("input");// input要素の value属性の値を取り出すvar text = input.value;var output = document.getElementById("output");output.innerHTML = "こんにちは," + text + "さん";
}</script></head><body><p><button onclick="greet()">挨拶</button></p><p>お名前: <input type="text" id="input" /></p><p><span id="output"></span></p></body></html>
3.3.2 数値の入力
上記の例では,テキスト(文字列)を入力するものでした.文字列のままでは,数として扱うこと
はできません.数値として扱うためには,文字列を数値に変換することが必要です.JavaScript に
は,文字列から数値に変換する関数 (Number)が用意されており,Number関数を用いて文字列を数
値に変換することができます.
文字列と数値の違いを調べるために次のプログラムを実行してみましょう.
<html>
15
<head><title>文字列と数値</title><script type="text/javascript">var str = "10";var num = Number(str);document.write("文字列: ", str + 1, "<br/>");document.write("数値: ", num + 1, "<br/>");</script></head><body></body></html>
最初の行は文字列として「足し算」を行うものです.文字列としての「足し算」は文字列をつなげる
ことになります.この例では,"10"という文字列と 1(これ自体は数値ですが,文字列の「足し算」
を行う場合は,文字列に直されてから「足し算」が行われます)をつなげて 101を出力します.
次の行は Number関数により"10"という文字列が,10という数値に変換されるため,数値として
の「足し算」になりますので,11 (= 10 + 1)が出力されます.
なお,Number関数に数に変換できない文字列を渡すと NaN(Not a Number)が返ります.例えば,
Number("10.0.1")は NaNになります(小数点が複数あるので数値にはなりません).また,いわゆ
る全角文字も数値には変換できませんので,10の代わりに10を与えると NaNの結果になります.
以下に,ボタンをクリックすると入力された二つの数の和を求めるプログラムを示します.
<html><head><title>足し算</title><script type="text/javascript">function add() {var input1 = document.getElementById("input1");// input1要素の value属性の値を取り出すvar text1 = input1.value;// 数値に変換するvar num1 = Number(text1);// input2についても同様に扱う.var input2 = document.getElementById("input2");var text2 = input2.value;var num2 = Number(text2);// 和を求めるvar sum = num1 + num2;// 出力するvar output = document.getElementById("output");output.innerHTML = sum;
}</script></head><body><p><button onclick="add()">計算</button></p><p><input type="text" id="input1" /> +
<input type="text" id="input2" /> =<span id="output"></span></p>
</body></html>
16
このプログラムでは,入力エリアが二つ表示されます.入力エリアに数をいれて,ボタンをクリック
すると二つの数の和が横に表示されます.数以外を入力すると,NaNが表示されることになります.
[練習問題 14] 上記の例を改造して二つの数の積を計算するプログラムを作成しなさい.
上記の例では演算の種類は固定になっていました.足し算と掛け算とを選択できるように改造して
みましょう.演算子の選択肢を表示するためには selectタグを用います.選択肢は optionタグを
用いて表します.次の例は二つの選択肢をメニューで提示します.
<select id="op"><option value="+">+</option><option value="*">×</option>
</select>
ユーザが選択した演算子を JavaScriptプログラムで求めるには,まず,idが opの HTML要素を
求め,その value属性の値を調べます.選択されている optionの value属性に指定された値 (+, *
のいずれか)が得られます.これにより,どの演算子が指定されているかがわかるので,演算子に応
じて計算の方法を変えることになります.
以下にプログラム例の全体を示します.
<html><head><title>足し算・掛け算</title><script type="text/javascript">function calculate() {var input1 = document.getElementById("input1");// input1要素の value属性の値を取り出すvar text1 = input1.value;// 数値に変換するvar num1 = Number(text1);// input2についても同様に扱う.var input2 = document.getElementById("input2");var text2 = input2.value;var num2 = Number(text2);// 演算子のHTML要素を求めるvar op = document.getElementById("op");// 演算子の選択肢の値を求めるvar optext = op.value;// 結果を入れる変数にはNaNを入れておくvar result = NaN;if (optext == "+") {result = num1 + num2;
} else if (optext == "*") {result = num1 * num2;
}// 演算結果を出力するvar output = document.getElementById("output");output.innerHTML = result;
}</script></head>
17
<body><p><button onclick="calculate()">計算</button></p><p><input type="text" id="input1" />
<select id="op"><option value="+">+</option><option value="*">×</option>
</select><input type="text" id="input2" /> =<span id="output"></span></p>
</body></html>
[練習問題 15] 上記の例を拡張して,四則演算 (+, -, *, /)に対応するようにしなさい.
4 タイマーとその応用
4.1 タイマー関数
setTimeout関数を使用して,指定した時間が経過した時に指定した関数を実行させることができ
ます.setTimeout関数は,実行する関数と実行させるまでの時間を引数としてとります.時間はミ
リ秒 (1000分の 1秒)の単位で表現します.
以下に例を示します.
<html><head><title>setTimeoutの例</title><script type="text/javascript">function test() {var input = document.getElementById("input");// input要素の value属性の値を取り出すvar text = input.value;var output = document.getElementById("output");// textを出力するoutput.innerHTML = "こんにちは," + text + "さん";
}function testdelay() {setTimeout(test, 1000);
}</script></head><body><p><button onclick="testdelay()">一秒後に挨拶</button></p><p>お名前: <input type="text" id="input" /></p><p><span id="output"></span></p></body></html>
この例では,ボタンをクリックすると,testdelay 関数が実行されます.testdelay関数は,test
関数を 1秒 (= 1000 ミリ秒) 後に実行するように setTimeout関数を呼び出しています.test関数
18
は,id属性が inputの入力エリアに入力されたテキストをもとに,id属性が outputの要素を書き
換えます.
[練習問題 16] 上記のプログラムを拡張して,実行を遅らせる時間を入力できるように入力エリア
を設けなさい.
解答例を以下に示します.ここでは,inputタグの value属性で入力エリアにあらかじめ入る初
期値を指定しています.ここでは,遅延時間の初期値として 1000を指定しています.
<html><head><title>遅れて挨拶</title><script type="text/javascript">function test() {var input = document.getElementById("input");// input要素の value属性の値を取り出すvar text = input.value;var output = document.getElementById("output");// textを入力するoutput.innerHTML = "こんにちは," + text + "さん";
}function testdelay() {// 遅延時間を求めるvar delay = document.getElementById("delay");var delayTime = Number(delay.value);setTimeout(test, delayTime);
}</script></head><body><p><button onclick="testdelay()">遅れて挨拶</button>遅延時間<input type="text" id="delay" value="1000" />(ミリ秒)</p>
<p>お名前: <input type="text" id="input" /></p><p><span id="output"></span></p></body></html>
4.2 時間をおいた繰り返し
setTimeout関数は指定された時間が経過した後に実行する関数を指定できるものでした.実行す
る関数の中で setTimeout関数を呼ぶことにより時間間隔をあけながら繰り返すことができます.
例えば,指定された時間間隔ごとにカウントダウンするプログラムを考えてみましょう.ここで
は,カウントダウンを開始する数字と,カウントダウンする時間間隔を入力させるようにしていま
す.ボタンをクリックするとカウントダウンを開始します.プログラムの例を以下に示します.
<html><head><title>カウントダウン</title><script type="text/javascript">function countdown() {
19
// 時間間隔を求めるvar delayNode = document.getElementById("delay");var delay = Number(delayNode.value);// カウントダウンの開始する値を求めるvar countNode = document.getElementById("count");var count = Number(countNode.value);var output = document.getElementById("output");function next() {// カウントを出力するoutput.innerHTML = count;if (count > 0) {// 数が正であれば繰り返すcount = count - 1;setTimeout(next, delay);
}}// 上で定義したnext関数を呼び出すnext();
}</script></head><body><p>スタート: <input type="text" id="count" value="10" />間隔: <input type="text" id="delay" value="100" />(ミリ秒)</p>
<p><button onclick="countdown()">カウントダウン</button></p><p><span id="output"></span></p></body></html>
ボタンをクリックすると countdown関数が呼び出されます.countdown関数の中で,新たに next
という関数を定義しています.このように関数の中に新たに関数を定義することができます.next
関数では,現在のカウントの値を出力するとともにその値が 0より大きければ,一つカウントを減じ
た上で,setTimeout関数を呼び出し,指定時間後に next関数を呼び出すようにしています.なお,
next関数の中では,関数の外側で定義された変数 (count, outputなど)にアクセスすることができ
ます.
[練習問題 17] 上記のプログラムを修正して,1から指定された数までカウントアップするプログ
ラムを作成しなさい.
5 放物運動の簡易アニメーション表示
ここでは,放物運動の動きを簡易アニメーションで表示する JavaScriptプログラムを考えてみま
しょう.
5.1 物体の表示
ブラウザのウィンドウ上に放物運動をする物体を表現することを考えます.ここでは簡単にするた
めに文字 (●)を含んだ span要素をウィンドウの指定の位置に表示させることにより,物体を表現す
20
ることにします.
ウィンドウ上の指定した位置に HTML 要素を表示するには「スタイル」を活用します.
JavaScript からは,style 属性によりスタイルにアクセスできます.まず,スタイルとして,
position: absoluteを指定することにより,HTML要素をウィンドウの左上からの指定された位
置に表示させることができます.水平方向 (x 方向) の位置は left で, 垂直方向 (y 方向) の位置は
topで指定します.下の例では,ウィンドウの左上の端に置かれることを表しています.pxはディ
スプレイ上のピクセル(ドット)を示す単位です.なお,topで指定する値が大きくなる程,ウィン
ドウの下の方に表示されます.
<html><head><title>物体の表現</title></head><body><span style="position:absolute; left: 0px; top: 0px">●</span></body></html>
5.2 表示位置の指定
次に●の文字を指定の位置に動かす関数を定義してみましょう.関数に汎用性を持たせるために引
数として HTML要素と動かす先の座標をとるものとします.
スタイルで指定された位置は HTML要素の左上の位置になります.そのため,文字が表示される
位置と指定された位置が多少ずれます.ここでは,HTML要素の中心が指定された座標に来るように
HTML要素の幅と高さの 1/2だけ補正することにします.HTML要素の幅と高さは clientWidth,
clientHeigth の属性により求めることができます*1.また,left, top を設定する際には,単位
(px)の文字列を付加します.
以下の例では,ボタンをクリックすると原点 (ウィンドウの左上の端)に文字が移動します.
<html><head><title>物体の原点への移動</title><script type="text/javascript">function move(obj, x, y) {// 中心を指定された座標に移動させるために補正量を求めるvar offsetx = obj.clientWidth / 2;var offsety = obj.clientHeight / 2;// スタイルのleftと topを設定するobj.style.left = (x - offsetx) + "px";obj.style.top = (y - offsety) + "px";
}function test() {var obj = document.getElementById("obj");// 原点に動かすmove(obj, 0, 0);
}</script>
*1 簡単にするため,margin, borderの HTML要素の枠に相当する領域は無視することにします.
21
</head><!-- はみ出してもスクロールバーが表示されないようにする.--><body style="overflow: hidden"><button onclick="test()">テスト</button><span id="obj" style="position:absolute;vertical-align: middle; text-align: center">●</span></body></html>
ここでは,span要素に vertical-alignを middleにすることで,表示する●の文字ができるだけ
span要素の中央に配置されるようにしています.また,bodyの style属性に overflow: hidden
を指定することにより,ブラウザのウィンドウにスクロールバーが出現しないようにしています.
5.3 移動の簡易アニメーション
次に setTimeout関数をつかって,●の文字を動してみましょう.以下に例を示します.
<html><head><title>物体の移動 (簡易アニメーション)</title><script type="text/javascript">function move(obj, x, y) {var offsetx = obj.clientWidth / 2;var offsety = obj.clientHeight / 2;obj.style.left = (x - offsetx) + "px";obj.style.top = (y - offsety) + "px";
}function start() {// 初期位置を求めるvar xpos = Number(document.getElementById("xpos").value);var ypos = Number(document.getElementById("ypos").value);// speedを求めるvar speed = Number(document.getElementById("speed").value);// 40ミリ秒ごとに更新するとする (毎秒 25回位置を更新する)var delay = 40;// 更新ごとの移動距離を求めるvar delta = speed * delay / 1000;function next() {var obj = document.getElementById("obj");// (xpos, ypos)の位置に動かすmove(obj, xpos, ypos);// xpos, yposが共に正である間は繰り返す// &&は論理積 (AND)を意味します.if ((xpos > 0) && (ypos > 0)) {xpos = xpos - delta;ypos = ypos - delta;setTimeout(next, delay);
}}// 上で定義したnext関数を呼び出すnext();
}</script></head>
22
<body style="overflow: hidden"><p>スタート位置: (<input type="text" id="xpos" value="200" />,<input type="text" id="ypos" value="200" />)</p>
<p>x, y方向の速度: <input type="text" id="speed" value="200" />(dot/sec)</p><p><button onclick="start()">スタート</button></p><span id="obj" style="position: absolute; left: -100px; top: -100px;vertical-align: middle; text-align: center">●</span></body></html>
初期位置と速度をユーザに入力させて,初期位置から原点 (ウィンドウの左上)に向かって移動させ
るようにしています(x, y 座標が共に正の値である間は移動し続けます).また,40ミリ秒ごとに位
置を更新しています.
5.3.1 ウィンドウ内の反射
次に物体がウィンドウの中を反射して動きまわるように修正してみましょう.ウィンドウの大きさ
を求めるために,window.innerWidthと window.innerHeightを使います.
<html><head><title>物体の移動 (ウィンドウ内の反射)</title><script type="text/javascript">function move(obj, x, y) {var offsetx = obj.clientWidth / 2;var offsety = obj.clientHeight / 2;obj.style.left = (x - offsetx) + "px";obj.style.top = (y - offsety) + "px";
}function start() {// 初期位置を求めるvar xpos = Number(document.getElementById("xpos").value);var ypos = Number(document.getElementById("ypos").value);// speedを求めるvar speed = Number(document.getElementById("speed").value);// 40ミリ秒ごとに更新するとする (毎秒 25回位置を更新する)var delay = 40;// 40ミリ秒ごとの移動距離の絶対値を求めるvar delta = Math.abs(speed * delay / 1000);var xdelta = delta;var ydelta = delta;function next() {var obj = document.getElementById("obj");// (xpos, ypos)の位置に動かすmove(obj, xpos, ypos);// ウィンドウの大きさを求めるvar width = window.innerWidth;var height = window.innerHeight;// 現在の位置に応じて,動かす方向を決めるif (xpos < 0) {xdelta = - delta;
}if (ypos < 0) {ydelta = - delta;
23
}if (xpos > width) {xdelta = delta;
}if (ypos > height) {ydelta = delta;
}xpos = xpos - xdelta;ypos = ypos - ydelta;setTimeout(next, delay);
}// 上で定義したnext関数を呼び出すnext();
}</script></head><!-- はみ出してもスクロールバーが表示されないようにする.--><body style="overflow: hidden"><p>スタート位置: (<input type="text" id="xpos" value="200" />,<input type="text" id="ypos" value="200" />)</p>
<p>x, y方向の速度: <input type="text" id="speed" value="200" />(px/sec)</p><p><button onclick="start()">スタート</button></p><span id="obj" style="position:absolute; left: -100px; top: -100px;vertical-align: middle; text-align: center">●</span></body></html>
スタートのボタンをクリックすると物体が動き出し,ウィンドウの枠内で反射する運動を繰り返し
ます.物体の位置に応じて,移動距離の符号を変えています.また,止めるには,HTML文書をリ
ロードすることになります.
このプログラムでは,動いている間に再びスタートボタンを押すと,同じ文字の表示の位置が何度
もセットされることになり,表示がちらつきます.そこで,スタートボタンを押すたびに新たに文字
の HTML要素を作成して,それを動かすように改造してみます.具体的には,start関数の中で,
新たに HTML要素を作り,適当にスタイルを設定した上で,HTML文書に追加します.JavaScript
プログラムとしては,document.createElement("span")により,spanタグの要素を作成します.
作成した要素は,document.body.appendChildにより HTML文書に追加します.以下の例では,
start関数が実行されるたびに物体を表す span要素が新たに作成されて,その位置が動くことにな
ります.
<html><head><title>複数の物体の移動 (ウィンドウ内の反射)</title><script type="text/javascript">function move(obj, x, y) {var offsetx = obj.clientWidth / 2;var offsety = obj.clientHeight / 2;obj.style.left = (x - offsetx) + "px";obj.style.top = (y - offsety) + "px";
}function start() {// HTML要素を毎回生成するvar obj = document.createElement("span");
24
obj.style.position = "absolute";obj.style.verticalAlign = "middle";obj.style.textAlign = "center";obj.innerHTML = "●";// objを追加するdocument.body.appendChild(obj);// 初期位置を求めるvar xpos = Number(document.getElementById("xpos").value);var ypos = Number(document.getElementById("ypos").value);// speedを求めるvar speed = Number(document.getElementById("speed").value);// 40ミリ秒ごとに更新するとする (毎秒 25回位置を更新する)var delay = 40;// 40ミリ秒ごとの移動距離を求めるvar delta = Math.abs(speed * delay / 1000);var xdelta = delta;var ydelta = delta;function next() {// (xpos, ypos)の位置に動かすmove(obj, xpos, ypos);// ウィンドウの大きさを求めるvar width = window.innerWidth;var height = window.innerHeight;if (xpos < 0) {xdelta = - delta;
}if (ypos < 0) {ydelta = - delta;
}if (xpos > width) {xdelta = delta;
}if (ypos > height) {ydelta = delta;
}xpos = xpos - xdelta;ypos = ypos - ydelta;setTimeout(next, delay);
}// 上で定義したnext関数を呼び出すnext();
}</script></head><!-- はみ出してもスクロールバーが表示されないようにする.--><body style="overflow: hidden"><p>スタート位置: (<input type="text" id="xpos" value="200" />,<input type="text" id="ypos" value="200" />)</p>
<p>x, y方向の速度: <input type="text" id="speed" value="200" />(px/sec)</p><p><button onclick="start()">スタート</button></p></body></html>
25
5.4 放物運動の表現
次に放物運動の動きを簡単なアニメーションで表示してみます.座標 (0, 0)の位置から初速 v0,仰
角 θ で打ち上げられた物体の t秒後の位置 (x(t), y(t))は次の式で表されます*2.
x(t) = (v0 cos θ)t
y(t) = −1
2gt2 + (v0 sin θ)t
ここで,g は重力加速度を表します.
x(t)を求める JavaScriptの関数を posx,y(t)を求める関数を posyとすると,次のように書けま
す.ここでは,初速を v0,仰角を theta,また重力加速度を g の変数で表しています.
// 初速var v0 = 60;// 仰角var theta = 0;// 重力加速度var g = 9.8;// t秒後の x座標function posx(t) {return v0 * Math.cos(theta) * t;
}// t秒後の y座標function posy(t) {return - (1 / 2) * g * t * t + v0 * Math.sin(theta) * t;
}
JavaScriptでは sin, cosは,それぞれ Math.sin, Math.cosの関数で求めることができます.引
数の単位はラジアンになります (180度 = π ラジアン).また,JavaScriptでは,π は Math.PIとし
て定義されています.
これらをまとめて,放物運動の簡易アニメーションを表示するプログラム例を以下に示しま
す.初速の大きさと仰角はユーザが入力できるようにしています.また,ウィンドウの右下の座
標を (0, 0) として,画面の上方向を y 方向の向きとしています.このため,move 関数において,
ウィンドウの高さから指定された座標 y の値を引くように修正しています.ウィンドウの高さは,
window.innerHeightで求めています.
<html><head><title>放物運動の軌跡</title><script type="text/javascript">// Y方向の座標の向きを変えているfunction move(obj, x, y) {var offsetx = obj.clientWidth / 2;
*2 ここでは,JavaScriptのプログラムの例題という位置づけで,時刻 tの物体の座標が式で与えられている場合を想定します.実際の物体の動きを求める時には必ずしも式として求められない場合も多く,その場合は近似解を数値計算により求めます.数値計算による手法は大学で勉強する範囲になりますので,ここでは扱わないことにします.
26
var offsety = obj.clientHeight / 2;var height = window.innerHeight;obj.style.left = (x - offsetx) + "px";obj.style.top = (height - y - offsety) + "px";
}function start() {var obj = document.createElement("span");obj.style.position = "absolute";obj.style.verticalAlign = "middle";obj.style.textAlign = "center";obj.innerHTML = "●";// objを追加するdocument.body.appendChild(obj);// 初速 (の絶対値)を求めるvar v0 = Math.abs(Number(document.getElementById("speed").value));// 仰角を求めるvar theta = Number(document.getElementById("theta").value) / 180 * Math.
PI;// 重力加速度var g = 9.8;// 40ミリ秒ごとに更新するとする (毎秒 25回位置を更新する)var delay = 40;// t秒後の x座標function posx(t) {return v0 * Math.cos(theta) * t;
}// t秒後の y座標function posy(t) {return - (1 / 2) * g * t * t + v0 * Math.sin(theta) * t;
}// 時間var t = 0;// 座標var x = 0;var y = 0;// 繰り返し用の関数を定義するfunction next() {x = posx(t);y = posy(t);move(obj, x, y);// yが 0以上の間は続けるif (y >= 0) {t = t + delay / 1000;setTimeout(next, delay);
}}// 上で定義したnext関数を呼び出すnext();
}</script></head><!-- はみ出してもスクロールバーが表示されないようにする.--><body style="overflow: hidden"><p>初速: <input type="text" id="speed" value="60" />仰角: <input type="text" id="theta" value="45" />度</p>
27
<p><button onclick="start()">スタート</button></p></body></html>
[練習問題 18] 初速や仰角のパラメータを変えてどのように動きが変化するか試してみよう.
5.5 重力加速度の切り替え
月面では重力加速度が地球表面の約 1/6の 1.62m/s2 になります.また,火星表面では,地球表面
の約 1/3の 3.71m/s2 になります.放物運動の軌跡を表示するプログラムを改造して,月面や火星表
面では放物運動がどのように変化するか表示してみましょう.なお,空気が存在しても空気による抵
抗は無視するものとします.
まず,場所を入力させるために selectタグを使用します.次の例は三つの選択肢をメニューで提
示します.
<select id="place"><option value="earth">地球</option><option value="moon">月</option><option value="mars">火星</option>
</select>
ユーザが選択した場所は,id属性が placeの HTML要素を求め,その value属性を調べることに
より求められます.選択されている optionの value属性に指定された値(earth, moon, marsのい
ずれか)が得られるので,その値に応じて重力加速度の値を変えることになります.
以下にプログラム例を示します.ここでは,重力加速度を変えるのにあわせて月の場合は,青,火
星の場合は,赤で物体を表示するように修正しています.色の指定は,スタイル属性の colorを指
定することにより行えます.
<html><head><title>放物運動の軌跡 (地球・月・火星)</title><script type="text/javascript">function move(obj, x, y) {var offsetx = obj.clientWidth / 2;var offsety = obj.clientHeight / 2;var height = window.innerHeight;obj.style.left = (x - offsetx) + "px";obj.style.top = (height - y - offsety) + "px";
}function start() {var obj = document.createElement("span");obj.style.position = "absolute";obj.style.verticalAlign = "middle";obj.style.textAlign = "center";obj.innerHTML = "●";// objを追加するdocument.body.appendChild(obj);
28
// 初速 (の絶対値)を求めるvar v0 = Math.abs(Number(document.getElementById("speed").value));// 仰角を求めるvar theta = Number(document.getElementById("theta").value) / 180 * Math.
PI;// 場所を求めるvar place = document.getElementById("place").value;// 重力加速度var g = 9.8;// 物体の色var color = "black";if (place == "moon") {// 月の重力加速度は,1.62 m/s2g = 1.62;color = "blue";
} else if (place == "mars") {// 火星の重力加速度は,3.71 m/s2g = 3.71;color = "red";
}// 物体の色を設定obj.style.color = color;// 40ミリ秒ごとに更新するとする (毎秒 25回位置を更新する)var delay = 40;// t秒後の x座標function posx(t) {return v0 * Math.cos(theta) * t;
}// t秒後の y座標function posy(t) {return - (1 / 2) * g * t * t + v0 * Math.sin(theta) * t;
}// 時間var t = 0;// 座標var x = 0;var y = 0;// 繰り返し用の関数を定義するfunction next() {x = posx(t);y = posy(t);move(obj, x, y);// yが負の値にならない間は続けるif (y >= 0) {t = t + delay / 1000;setTimeout(next, delay);
}}// 上で定義したnext関数を呼び出すnext();
}</script></head><!-- はみ出してもスクロールバーが表示されないようにする.--><body style="overflow: hidden">
29
<p>初速: <input type="text" id="speed" value="30" />仰角: <input type="text" id="theta" value="45" />度<select id="place"><option value="earth">地球</option><option value="moon">月</option><option value="mars">火星</option></select></p><p><button onclick="start()">スタート</button></p></body></html>
[練習問題 19] 月や火星以外に,例えば,金星や木星などの惑星などの重力加速度を調べて,どの
ように軌跡が変わるか試してみよう.
5.6 軌跡の表現
さらに物体の運動の軌跡を残すようにしてみましょう.ここでは,物体の位置を動かすたびに軌跡
を表現する文字を追加していくことを考えます.
まず,軌跡を追加・表示する関数 (ここでは addTraceと名づけます) を定義します.この関数は,
物体と同様に HTML要素を新たに追加していきます.関数の引数としては,物体を表す HTML要
素を渡し,それから位置や色などの情報をコピーします.また,下の例では,・の文字を使用してい
ます.さらに,style属性の opacity(不透明度)の値を設定して,半透明で表示されるようにして
います.opacityは,0から 1の値をとり,0で透明になり,1で完全に不透明になります.
function addTrace(obj) {// 軌跡表示用のHTML要素を作成するvar trace = document.createElement("span");trace.style.position = "absolute";trace.style.verticalAlign = "middle";trace.style.textAlign = "center";trace.innerHTML = "・";// 位置や色をコピーするtrace.style.top = obj.style.top;trace.style.left = obj.style.left;trace.style.color = obj.style.color;// 軌跡に不透明度 (0 -- 1の間の値)を設定するtrace.style.opacity = 0.1;// traceを追加するdocument.body.appendChild(trace);
}
また,軌跡を残すか否かは checkbox を使って指定させるようにします.input タグを使用し,
type属性として checkboxを指定します.
<p>トレース: <input type="checkbox" id="trace" /></p>
30
JavaScript プログラムからは,id 属性が trace の HTML 要素の checked を調べることにより,
チェックが入っているかを確認できます.チェックが入っている場合には checkedの値が trueの
値になります.
これらを使用したプログラム例を以下に示します.
<html><head><title>放物運動の軌跡 (地球・月・火星)</title><script type="text/javascript">function move(obj, x, y) {var offsetx = obj.clientWidth / 2;var offsety = obj.clientHeight / 2;var height = window.innerHeight;obj.style.left = (x - offsetx) + "px";obj.style.top = (height - y - offsety) + "px";
}// objの軌跡を残すfunction addTrace(obj) {// 軌跡表示用のHTML要素を作成するvar trace = document.createElement("span");trace.style.position = "absolute";trace.style.verticalAlign = "middle";trace.style.textAlign = "center";trace.innerHTML = "・";// 位置や色をコピーするtrace.style.top = obj.style.top;trace.style.left = obj.style.left;trace.style.color = obj.style.color;// 軌跡に不透明度 (0 -- 1の間の値)を設定するtrace.style.opacity = 0.1;// traceを追加するdocument.body.appendChild(trace);
}function start() {var obj = document.createElement("span");obj.style.position = "absolute";obj.style.verticalAlign = "middle";obj.style.textAlign = "center";obj.innerHTML = "●";// objを追加するdocument.body.appendChild(obj);// 初速 (の絶対値)を求めるvar v0 = Math.abs(Number(document.getElementById("speed").value));// 仰角を求めるvar theta = Number(document.getElementById("theta").value) / 180 * Math.
PI;// 場所を求めるvar place = document.getElementById("place").value;// 重力加速度var g = 9.8;// 物体の色var color = "black";if (place == "moon") {// 月の重力加速度は,1.62 m/s2g = 1.62;
31
color = "blue";} else if (place == "mars") {// 火星の重力加速度は,3.71 m/s2g = 3.71;color = "red";
}// 物体の色を設定obj.style.color = color;// 40ミリ秒ごとに更新するとする (毎秒 25回位置を更新する)var delay = 40;// t秒後の x座標function posx(t) {return v0 * Math.cos(theta) * t;
}// t秒後の y座標function posy(t) {return - (1 / 2) * g * t * t + v0 * Math.sin(theta) * t;
}// 時間var t = 0;// 座標var x = 0;var y = 0;// 繰り返し用の関数を定義するfunction next() {x = posx(t);y = posy(t);move(obj, x, y);// 跡を残すかチェックvar trace = document.getElementById("trace").checked;// チェックが入っていれば,trueになるif (trace) {addTrace(obj);
}// yが負の値にならない間は続けるif (y >= 0) {t = t + delay / 1000;setTimeout(next, delay);
}}// 上で定義したnext関数を呼び出すnext();
}</script></head><!-- はみ出してもスクロールバーが表示されないようにする.--><body style="overflow: hidden"><p>初速: <input type="text" id="speed" value="30" />仰角: <input type="text" id="theta" value="45" />度<select id="place"><option value="earth">地球</option><option value="moon">月</option><option value="mars">火星</option></select>
32
トレース: <input type="checkbox" id="trace" /></p><p><button onclick="start()">スタート</button></p></body></html>
[練習問題 20] これまでは,原点の座標 (0, 0)から物体を投げていました.これを高さ h の場所,
すなわち座標 (0, h)から物体を投げ上げるように改造しなさい.高さ hはユーザが入力できるも
のとします.
33
付録 A JavaScript実験環境 (JSWorkbench)
JavaScript のごく簡単な実験環境 (’JSWorkbench’) を用意しています.URL は http://jsw.
semlab.jp/です.ここで,例題の動作確認を確認を行うことができます.推奨ブラウザは,Firefox
3.6以上です.図 1に画面例を示します*3.
ここにHTML (JavaScript)を書きます
あらかじめ用意されている例題を読み込めます
ボタンをクリックするとHTMLの表示エリアに反映されます
図 1 JSWorkbenchの画面例
画面の左側には HTMLの編集エリア,右側には HTMLの表示エリアが配置されています.編集
エリアに HTML(JavaScript)を書きます.表示エリアの上の「すぐに更新」のボタンをクリックす
ることにより,編集エリアの HTMLが表示エリアに反映されます.なお,編集エリアの上の「自動
更新」のチェックボックスをオンにしておくと,修正した内容が随時表示に反映されます.
また,事前学習資料の例題を読み込めるようになっています.メニューから選択して,動作を確認
してみてください.HTML編集エリアに入力したプログラムを,パソコン上にファイルとして保存
するためには,「ファイルへの書き出し」を実行します.また,パソコン上ファイルを読み込む場合
は,「ファイルから読み込み」を実行します.
HTMLの編集エリアには CodeMirror 2*4 を使用して,HTMLや JavaScriptの編集の利便性を
向上させています.行番号をつけたり,HTMLや JavaScriptの予約語の色付けができます.また,
エラーが発生した時は,行番号をもとにエラーの発生箇所を調べることができます.
現状では,以下の制限があります.
• ファイルへの書き出しは,一旦,サーバに編集内容を送信して,サーバからそのデータをファイルへダウンロードすることで行います (JavaScript プログラムから直接 PC上のファイルシ
*3 JSWorkbenchのバージョンアップにより細部の表示は変更されることがあります.*4 http://codemirror.net/
34
ステムにアクセスできないため).ブラウザによっては,別ページに遷移するなど挙動が変わ
る場合があります.
• 最初にアクセスした際に例題の読み込みがうまくいかず,行番号の表示がおかしくなる症状が残っています.この症状が出た場合は,例題の再読込を試してみてください.
35
付録 B Firefox のダウンロード・インストール
本アドバンストプログラムの JavaScript学習資料を独習するにあたっては,一般のブラウザを利
用できますが,エラーの表示機能やデバッガ(プログラムの間違いを発見して訂正するための道具)
が充実している,Mozilla Firefoxブラウザが便利です.Mozilla Firefoxブラウザは無料でインター
ネットからダウンロードして利用することができます.ここではMozilla Firefoxのダウンロードお
よびインストールの手順について説明します.
以下の説明ではWindows XPへのインストールを例に説明をしますが,ほかのWindows OSで
もほぼ同じ手順でインストールできます.またMozilla FirefoxにはMacOSや Linux OS用のもの
もあります.
なおインストール作業は,すべて管理者権限を持つユーザで行う必要があります.
Internet Explorer を利用して Firefox をダウンロードします.
1. Internet Explorerブラウザを起動します.[スタート]メニューから,[インターネット]を選
択します.
2. アドレスバーに,http://mozilla.jp/firefox/と入力して,Mozilla Japan のサイトを参
照します*5.
3.「無料ダウンロード」と書かれているリンクがありますので,これをクリックします.
4. ダウンロードダイアログが開いたら,[実行 (R)] を選択します.
5. インストーラファイルの容量は,おおよそ 8MBほどあります.インストールプログラムのダ
ウンロード後,インストーラが起動し,インストールが開始されます.
*5 Firefoxのバージョンアップにより,表示が大きく変わっている可能性はあります.ここでは,バージョン 3.6 以上を推奨します.
36
6. ダウンロードが完了すると,インストーラが実行されようとしますが,「Internet Explorer -
セキュリティの警告」が表示され,「このソフトウェアを実行しますか?」と表示されます.矢
印で示した「発行元:」が,「Mozilla Corporation」となっていることを確認して,[実行 (R)]
をクリックします.
※Windows Vista をご利用の場合は,「ユーザアカウント制御」が表示され,「プログラムを続
行するにはあなたの許可が必要です」と表示されます.同じように,「Mozilla Corporation」
となっていることを確認して,[続行 (C)] をクリックします.
7. 小さなウィンドウが表示された後,「Mozilla Firefox のセットアップ」画面が表示されます.
[次へ] を選択します.
37
8.「セットアップの種類」が表示され,Firefox のセットアップの種類を選びます.「標準インス
トール」を選んで,「次へ」をクリックします.
9.「セットアップ設定の確認」が表示され,Firefoxのインストール場所が表示されます.インス
トール場所を変更したい場合は変更します(通常はそのままでよい).Firefoxを既定のブラウ
ザ(普段使うブラウザ)にしたいときは「Firefoxを既定のブラウザとして使用する」にチェッ
クをいれます.そうでない場合はチェックをはずします.「インストール」をクリックします.
10. インストールが実行され,インストール状況が表示されます.
38
11. インストールが正常終了すると,「Mozilla Firefoxのセットアップが完了します」が表示され
ます.今すぐ Mozilla Firefox を起動] にチェックが入っていることを確認して,[完了] を選
択します.
12. Firefox が起動します.いままでに一度も Firefoxをインストールしたことがなければ,[設定
移行ウィザード] が開いて.Internet Explorer のブックマーク・お気に入りをインポートす
ることができます.起動時のホーム画面なども設定することができます.
13. 以上で Firefox のインストールは完了です.次回からは,デスクトップのMozilla Firefox を
ダブルクリックするか,スタートメニューから Firefox を起動できます.
39
付録 C Firefoxのエラーコンソール
Firefox にはエラーコンソールというツールが標準で搭載されており,HTML 文書に埋め込んだ
JavaScriptに記述の間違いなどがあった場合は,このコンソールウインドウ内に通知が表示されるこ
とがあります.通知によっては JavaScriptのどの行でエラーが起こったのかを表示してくれるので,
エラーの場所を特定しやすくなります.
C.1 エラーコンソールの表示の仕方
エラーコンソールを表示させるには,Firefoxのメニューバーの中にある,「ツール」メニューを開
いて,「エラーコンソール(C)」を選択します*6.
選択するとエラーコンソールが表示されます.
*6 メニューが見当たらない場合は,キーボードから Ctrl-Shift-J (コントロールキーとシフトキーを押しながら J のキーを押す)でもエラーコンソールを表示させられます.
40
エラーコンソールに表示される通知にはいくつか種類があります.エラーコンソールウインドウ上
部にあるタブボタンでそれらを選ぶことができます.重要性の比較的低い「メッセージ」や「警告」
は頻繁に表示されるので,「エラー」タブを選択して重要性の高い通知だけを表示するようにします.
関係のない通知がすでに表示されている場合は,消去ボタンを押すことでこれまでに通知されたもの
を削除することができます.
C.2 JavaScriptの課題をプログラム中に表示されるエラー通知の例
本アドバンストプログラムで提供される JavaScript 実験環境(JSWorkbench)をつかって
JavaScript のプログラムを書いている最中に,もしプログラムの記述に間違いがあった場合に
どのようなエラーがエラーコンソールに通知されるかを示します.
初心者によく見られるプログラムの間違いとして,引用符(’や")を正しく閉じていない,という
場合があります.上のプログラムでは「"a = 」の閉じ引用符"がひとつ抜けているために,正しく動
作しません.このようなプログラムを書いてから JSWorkbenchウインドウの HTMLの表示「すぐ
に更新」のボタンを押すとエラーコンソールには次のような通知が表示されます.
41
通知の1行目の「unterminated string literal」は,「文字列が正しく終端されていない(つまり引
用符がひとつ抜けているので対応がつかない引用符がある)」というエラーの内容を表しています.
2行目はエラーの起きた文書の URL です.この場合は JSWorkbench の URL が表示されてい
ます.
3行目はエラーの検知された場所を示す矢印です.文字列を表す引用符"は2つずつペアで使われ
なければなりませんが,この行には3つしかないので,ひとつ閉じ引用符が足りないまま関数の括弧
が閉じられたところでエラーとなりました.
これを訂正するにはどうすればよいかわかりますか? 間違いは矢印の場所そのものではなく,そ
の前後のどこかで間違いや抜けが起こっていることが多いので,それを探します.この場合は文字列
「"a = "」につづけて変数 aの内容を表示したかったのですが,「"a = 」と閉じ引用符を書き忘れて
しまったことが間違いでした.そこで正しい位置に引用符を追加してやると正しく動作して,変数 a
の内容が右画面に表示されるようになります.
正しく動作した場合にはエラーコンソールには新たになにも表示されません.以前通知されたエ
ラーは表示されたままになっているので,間違いを直してうまく動作したら,「消去」ボタンを押し
て以前の通知を消しておきましょう.
このようにして,エラーコンソールの表示を見ながらプログラムを書いていくとどこに間違いがあ
るのかを見つけやすくなりますので,活用してみてください.
42