Home > イヌでもわかるJavaScript講座 お品書き
イヌでもわかるJavaScript講座 お品書き へ戻ります
イヌでもわかるJavaScript講座


Step.30 - 電卓に挑戦


フォームとJavaScriptで、電卓を作ってみましょう。


Step テーマ
● eval - 計算式を求める

実行例


電 卓


リスト


<script type="text/javascript"><!--
myTotal = 0;// 現在の合計値
myInput = "";// 現在入力している値
myCalc = "+";// 合計と入力値の演算子
myFlg = 1;// 1回前に入力したもの 0:数字 1:演算子
 
function myValue(myData){// 0〜9または小数点ボタンを押した
myFlg = 0;// 1回前に入力したものは数値
myInput += myData;// 現在入力している値に追加
document.myForm.myLine.value = myInput;// 現在入力している値表示
}
 
function myCalculate(myData){// 演算ボタンを押した
if (myFlg==0){// 1回前に入力したものは数値か?
myFlg = 1;// 1回前に入力したものは演算子
myWork = myTotal + myCalc + myInput;// 一連の計算式を作る
myTotal = eval(myWork);// 計算式を計算させる
myInput = "";// 現在入力している値をクリア
document.myForm.myLine.value = myTotal;// 合計を表示
}
if (myData == "="){// 演算ボタンは[=]か?
myTotal = 0;// 合計をクリア
myCalc = "+";// 演算子を[+]とする
}else{// 演算ボタンは[=]以外である
myCalc = myData;// 演算子を退避させておく
}
}
 
function myC(){// クリアボタン[C]を押した
myTotal = 0;// 合計クリア
myCalc = "+";// 演算子クリア
myInput = "";// 現在入力している値をクリア
document.myForm.myLine.value = myTotal;// つまり、0を表示
}
// --></script>
 
<form name="myForm">
<table border="1" bgcolor="#BDB76B">
<tr>
<td align="center" colspan="4" bgcolor="#d2691e"><font color="#FFFFFF">
<strong> 電 卓</font></strong></td>
</tr>
<tr>
<td colspan="3"><input type="text" size="12" name="myLine" value="0"></td>
<td align="center"><input type="button" value="C" onclick="myC()"></td>
</tr>
<tr>
<td align="center"><input type="button" value=" 7 " onclick="myValue(7)"></td>
<td align="center"><input type="button" value=" 8 " onclick="myValue(8)"></td>
<td align="center"><input type="button" value=" 9 " onclick="myValue(9)"></td>
<td align="center"><input type="button" value="÷" onclick="myCalculate('/')"></td>
</tr>
<tr>
<td align="center"><input type="button" value=" 4 " onclick="myValue(4)"></td>
<td align="center"><input type="button" value=" 5 " onclick="myValue(5)"></td>
<td align="center"><input type="button" value=" 6 " onclick="myValue(6)"></td>
<td align="center"><input type="button" value="×" onclick="myCalculate('*')"></td>
</tr>
<tr>
<td align="center"><input type="button" value=" 1 " onclick="myValue(1)"></td>
<td align="center"><input type="button" value=" 2 " onclick="myValue(2)"></td>
<td align="center"><input type="button" value=" 3 " onclick="myValue(3)"></td>
<td align="center"><input type="button" value="−" onclick="myCalculate('-')"></td>
</tr>
<tr>
<td align="center"><input type="button" value=" 0 " onclick="myValue(0)"></td>
<td align="center"><input type="button" value=" ・ " onclick="myValue('.')"></td>
<td align="center"><input type="button" value=" + " onclick="myCalculate('+')"></td>
<td align="center"><input type="button" value="=" onclick="myCalculate('=')"></td>
</tr>
</table>
</form>



サンプルだけの HTMLは こちらへ

説明


電卓はカレンダーを作るより簡単です。
ボタンをこう押せば、こうなるという電卓の流れを言葉にすれば、それがプログラムになります。

では、言葉にしてみましょう。

まず、電源をいれます。表示されている数値は0です。 この数値を表示するところを以下「窓」と表現します。
窓は、2種類の数値を表示します。現在打ち込んでいる数値と、「+」や「−」を押したときの合計値です。

2種類あれば、変数も2つ用意しましょう。
myInput = ""; // 現在入力している値
myTotal = 0 ; // 現在の合計値

では、普段やってる電卓の操作を考えてみましょう。

100 + 200 + 300 + 400 =
とボタンを押す流れを言葉にしてみます。
まず、窓は0のはずです。
「1」を押すと窓は1に変わります。次に「0」を押して窓は10、そして100と表示されます。
「+」を押します。窓は100のままです。
「2」を押すと窓の100が消えて、2が表示されます。
「0」「0」と押して、窓は200になります。
「+」を押します。窓は、100+200 で300になります。このときの「+」は、前回押した「+」です。
この流れの繰り返しです。

プログラムは、数値を入力しているルーチン、演算ボタンを押したときのルーチンだけでよさそうです。
では、それぞれ、myValue()、myCalculate() という関数に処理を分けることにします。

電卓画面としては、それぞれのボタンをフォームボタンでつくります。
ボタンを押せば、押されたボタンの数値または演算子をパラメータにして、対応する関数を呼びます。
<input type="button" value=" 1 " onclick="myValue(1)">
<input type="button" value=" + " onclick="myCalculate('+')">

では、数値を入力しているルーチン myValue() を考えてみましょう
function myValue(myData){// 0〜9または小数点ボタンを押した
myFlg = 0;// 1回前に入力したものは数値
myInput += myData;// 現在入力している値に追加
document.myForm.myLine.value = myInput;// 現在入力している値表示
}
押された数字がパラメータでくるので、それを表示するだけです。
入力している数値は、myInput に格納するので、それにパラメータ myData をくっつけて、表示します。足している訳ではありません。
myInput が文字の数字のため、"1"+2 = "12" となります。

また、最初は、myInput に初期値として "" をセットしているので、""+1 = "1" です。
数値の1と数値の2を文字列 "12" としたい場合は、このように "" + 1 + 2 とします。

次に、演算ボタンを押したときのルーチン myCalculate() を考えてみましょう
function myCalculate(myData){// 演算ボタンを押した
if (myFlg==0){// 1回前に入力したものは数値か?
myFlg = 1;// 1回前に入力したものは演算子
myWork = myTotal + myCalc + myInput;// 一連の計算式を作る
myTotal = eval(myWork);// 計算式を計算させる
myInput = "";// 現在入力している値をクリア
document.myForm.myLine.value = myTotal;// 合計を表示
}
if (myData == "="){// 演算ボタンは[=]か?
myTotal = 0;// 合計をクリア
myCalc = "+";// 演算子を[+]とする
}else{// 演算ボタンは[=]以外である
myCalc = myData;// 演算子を退避させておく
}
}
先ほどの、電卓の操作の流れで、 「窓は100のままです。」、「このときの「+」は、前回押した「+」です。」といいました。
100[+] 「窓は100のままです。」
100[+]200[+] 「窓は300になります。このときの「+」は、前回押した「+」です。」

前回押した演算子を覚えておかないとわるいので、myCalc に退避させます。
最初の演算ボタンを押したとき、前回押した演算子は当然ありません。
そこで、初期値に "+" を myCalc に初期値をしてセットしておきます。
myCalc = "+"; // 合計と入力値の演算子
すると、0[+]100[+]という形になるので、「窓は100のままです。」と都合よくなります。

myWork = myTotal + myCalc + myInput; // 一連の計算式を作る
つまり、最初は
myWork = 0 + "+" + "100";
で、myWork は、
"0+100" という文字列がセットされます。

myTotal = eval(myWork); // 計算式を計算させる
eval() 関数は、計算式の文字列を計算して、結果を戻します。
これで、myTotal に、現在合計の100がセットされます。
この関数のおかげで、どんな演算ボタンが押されようが計算してくれるわけです。

myInput = ""; // 現在入力している値をクリア
入力した100は合計に加算されたので、次の数値を入力するためクリアします。

document.myForm.myLine.value = myTotal; // 合計を表示
現在の合計値を窓に表示しないといけないので、表示します。


さて、演算子で「=」だけは例外です。どう違うかというと、次が無い、終了ということです。
ですから、次の新たな計算のために、変数を初期化します。
「=」でない演算子だったら、myCalc に退避させて、あとで使います。
if (myData == "="){// 演算ボタンは[=]か?
myTotal = 0;// 合計をクリア
myCalc = "+";// 演算子を[+]とする
}else{// 演算ボタンは[=]以外である
myCalc = myData;// 演算子を退避させておく
}

さて、この一連の処理が、
if (myFlg == 0) { ・・・ }
の中にあります。
myFlg は、一体何なのでしょう。これは、以下のパターンのためのチェックです。
100[+]200[+][-]
こんな押し方をした場合です。連続して演算ボタンを押した場合、前回を取り消して、
100[+]200[-]
にしてあげるためのチェック変数です。
myFlg は、前回のボタンを記憶させて、演算ボタンを押した前が演算ボタンだったら、処理を素通りして、myCalc の内容だけを訂正するようにしました。
演算ボタンだったら1、数値だったら0がセットされています。


クリアボタン[C]を作るのを忘れていました。[C]を押すとこの関数を呼ぶようにします。
すべてを初期値に戻します。
function myC(){// クリアボタン[C]を押した
myTotal = 0;// 合計クリア
myCalc = "+";// 演算子クリア
myInput = "";// 現在入力している値をクリア
document.myForm.myLine.value = myTotal;// つまり、0を表示
}


あと、「00」ボタンや、「000」ボタンを付けようと思ったのですが、空きセルがないのであきらめました。
付けるのでしたら、
<td align="center"><input type="button" value="00" onclick="myValue('00')"></td>
<td align="center"><input type="button" value="000" onclick="myValue('000')"></td>
を追加するだけです。

訂正の[CE]ボタンも空きセルが無いため、省略です。間違ったら、最初からやり直しです。(^^;

Q&A


● 窓を右詰めにできませんか?
● スタイルシートで指定します。


<input style="text-align:right;" type="text" size="12" name="myLine" value="0">


 
イヌでもわかるJavaScript講座 お品書き へ戻ります