電卓 ver. 02

Javascriptで電卓を作成
0

【作者のコメント】 表示の桁があふれてしまった場合、先頭に"E"を付けて表示するようにした。


解説

Ver. 1からの変更点は以下の点である:

  1. calc.pngという画像で、木目調の外観にした。ボタンは、インラインのCSSでその位置を指定して表示するようにした。
  2. ディスプレイは、calc.pngの表示部分に一致するように、div要素(id="display")で表示するようにした。
  3. 掛け算[×]、割り算[÷]のボタンを追加した。
  4. 小数点[.]のボタンを追加した。
  5. 演算の後に入力した数字をクリアするボタン[C]を追加した。
  6. ディスプレイの表示が8桁を超えると、先頭に"E"をつけて8桁だけ表示するようにした。

外部設計(画面レイアウト)

44行目から71行目までのdiv要素で、電卓を表示している。

44: <div style="position: relative;">
45: <img src="./calc.png" height="459" width="300">
46: <div id="display">0</div>
47: 
48: <input value="7" onclick="button_down('7');" class="PButton" style="top:190px; left:70px;" type="button">
49: <input value="8" onclick="button_down('8');" class="PButton" style="top:190px; left:125px;" type="button">
50: <input value="9" onclick="button_down('9');" class="PButton" style="top:190px; left:180px;" type="button">
51: <input value="÷" onclick="button_div();" class="PButton" style="top:190px; left:235px;" type="button">
52: 
〜中略〜
65: 
66: <input value="AC" onclick="button_AC();" class="PButton" style="top:340px; left:15px;" type="button">
67: <input value="0" onclick="button_down('0');" class="PButton" style="top:340px; left:70px;" type="button">
68: <input value="." onclick="button_down('.');" class="PButton" style="top:340px; left:125px;" type="button">
69: <input value="=" onclick="button_equal();" class="PButton" style="top:340px; left:180px;" type="button">
70: <input value="+" onclick="button_plus();" class="PButton" style="top:340px; left:235px;" type="button">
71: </div>

45行目のimg要素でcalc.pngを表示して、木目調の外観の電卓の土台としている。calc.pngは、MS Wordのオートシェイプを使って画像を作成し、Wordの印刷プレビューで拡大して画面に表示し、そのスクリーンショットをpngファイルに変換して加工した。

46行目のdiv要素(id="display")が、ディスプレイである。CSS(#display)で表示位置を調整(left: 10px; top: 38px;)して、calc.pngの表示窓に一致するようにしてある。

ボタンについては、48行目以降にあるように、その表示位置をインラインのCSS(e.g. style="top:190px; left:70px;")で定めている。ボタンのinput要素のvalue属性の値は、ボタンに表示される文字である。例えば51行目のようにvalue="÷"とすることで、ボタンに÷を表示させている。onClickイベントハンドラーで関数を呼び出して処理しているところは、ver. 1と同様である。

内部設計

グローバル変数

Ver. 1と同様で、グローバル変数として以下の三つを使用している:

86: var accum = "0";	// 入力された数値の計算結果を蓄積していくための変数
87: var buffer = "";	// 入力された数字を繋げて数値として一時的に保持するための変数
88: var operator = "";	// +などの押された演算が何かを保持するための変数

accumは、accumulatorの略で、入力された数値や計算結果を蓄積しておく変数である。

bufferは、数字のボタンを押して入力される数字を記憶して、1ケタ以上の数字の列を格納するために使用する変数である。

operatorは、演算のボタンを押したときに、その演算を記憶しておくための変数である。

<div id="display" >の取得

Ver. 1のように<form>〜</form>は使用しないで、ディスプレイに表示される値を変更するためには、DOMツリーのノードとして<div id="display" >を取得して、値を変更することとした。そのために、document.getElementById()でDisplayという変数にdiv要素を取得する。すると、Displayを使って取得したdiv要素のプロパティを変更ができるようになる。getElementById("display")を実行するには、id="display"を持つ要素が定義されていなければならないので、46行目よりも後にこの命令を書かなければならない。

91: /* id=displayのDOMツリーノードの取得 */
92: var Display = document.getElementById("display");
93: /* ここで、メインルーチンは終わり */

関数(サブルーチン)

関数(サブルーチン)についての解説をする。

display_number()

ディスプレイに数字を表示するための関数である。ただし、8ケタを超えた場合は先頭に"E"を付して8ケタだけ表示する。148行目で、引数strを文字列mojiに変換し、その文字数moji.length(lengthプロパティ)が8文字を超えるかどうかを150行目のif文でチェックする。8文字を越えた場合は、部分文字列を切り出す関数moji.substring()(substringメソッド)で、最初から7文字分だけ切りだし、それを改めてmojiに代入する(151行目)。152行目でmojiの先頭に"E"を付け足す。155行目でDisplayに表示されれる文字を表す変数Display.textContent(textContentプロパティ)にmojiを代入すると、mojiがディスプレイに表示される。

153: function display_number(str)
154: {
155: 	var moji = new String(str);
156: 	/* 6桁表示にする*/
157: 	if( moji.length > 8 ){
158: 		moji = moji.substring(0, 7);
159:		moji = "E" + moji;
160: 	}
161: 	
162: 	Display.textContent = moji;
163: }

button_down()

数字だけではなく、小数点も入力するようにするため、ver. 1のbutton_num()の名前をbutton_down()とした。修正箇所は、document.calc.display.value = buffer;としていたところを、177行目のようにしただけである。数字と小数点がクリックされた時に呼び出すのは、このbutton_down()である。

179: function button_down(str)
180: {
181: 	if( operator == "" ){ accum = "";}
182: 	buffer = buffer + str;
183: 	
184: 	display_number(buffer);
185: }

button_clear()

[C]ボタンをクリックしたときは、[AC]ボタンと異なり、accumは初期化せず、bufferだけを初期化する。

172: function button_clear()
173: {
174: 	buffer = "";
175: 	var moji = new String(accum);
176: 	display_number(moji);
178: }

その他の関数

button_plus()、button_minus()、button_prod()、button_div()、button_equal()、button_AC()は、ディスプレイへの表示の部分がver. 1と異なるだけで、同様である。