質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

5回答

3558閲覧

イベントハンドラについて

ojgtmaga

総合スコア12

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2016/11/07 10:42

編集2016/11/09 09:16

質問があります。
電卓を作成しています(まだ途中です)。
電卓のファイルは以下の通りです。

html

1<!DOCTYPE html> 2<html lang="ja"> 3 <head> 4 <meta charset="utf8"> 5 <title>電卓</title> 6 </head> 7 <body> 8 電卓 9 <p> 10 <input id="ans" size="20" readonly></input><br> 11 <button id="one" > 1 </button> 12 <button id="two" > 2 </button> 13 <button id="three" > 3 </button> 14 <button id="four" > 4 </button> 15 <button id="five" > 5 </button><br> 16 <button id="six" > 6 </button> 17 <button id="seven"> 7 </button> 18 <button id="eight"> 8 </button> 19 <button id="nine"> 9 </button> 20 <button id="zero"> 0 </button><br> 21 <button id="plus"> + </button> 22 <button id="minus"> - </button> 23 <button id="mul"> * </button> 24 <button id="div" > / </button> 25 <button id="equ"> = </button> 26 27 </p> 28<script src="dentaku.js"></script> 29 </body> 30</html>

HTMLの実行結果です。
htmlの実行結果
そして、javascriptのファイルです。

javascript

1 var kotae = document.getElementById('ans'); 2 var iti = document.getElementById('one'); 3 var ni = document.getElementById('two'); 4 var san = document.getElementById('three'); 5 var yon = document.getElementById('four'); 6 var go = document.getElementById('five'); 7 var roku = document.getElementById('six'); 8 var nana = document.getElementById('seven'); 9 var hati = document.getElementById('eight'); 10 var kyu = document.getElementById('nine'); 11 var zyu = document.getElementById('zero'); 12 var tasu = document.getElementById('plus'); 13 var hiku = document.getElementById('minus'); 14 var kakeru = document.getElementById('mul'); 15 var waru = document.getElementById('div'); 16 var ikoru = document.getElementById('equ');

javascriptはDOMの取得で終わっています。
これから、例えば、1の数字のボタンを押したら、テキストボックスに1を表示したい場合、

javascript

1 2iti.onclick = click1; 3function click1(){ 4 kotae.textContent = '1'; 5 }

のようにやるのかと考え、htmlを開いてみたら、押しても反応しませんでした。このような方法では、テキストボックス上に表示できないのでしょうか?
また、このようなイベントハンドラを設定する際に、19の数字一つ一つ繰り返し入力しなければならないのでしょうか?19の数字全てに共通するイベントハンドラ(1~9の数字をクリックしたら、テキストボックス上にその数字を表示)を作成できないのかが知りたかったため、質問させていただきます。
まずは1桁の計算ができるようになりたいので、12とか32などの数字が入力されることは考えていません。
分かる方がいらっしゃいましたら、ご教示お願いします。

追記

javascript

1var kotae = document.getElementById('ans'); 2 var zeroToNine = ["zero", "one", "two", "three", "four", 3 "five", "six", "seven", "eight", "nine"]; 4 var digitElements = new Array(10); 5 var tasu = document.getElementById('plus'); 6 var hiku = document.getElementById('minus'); 7 var kakeru = document.getElementById('mul'); 8 var waru = document.getElementById('div'); 9 var ikoru = document.getElementById('equ'); 10 11 for (var i = 0; i <= 9; i++) { 12 digitElements[i] = document.getElementById(zeroToNine[i]); 13 digitElements[i].onclick = function() { 14 // アラビア数字に変換 15 var digit = zeroToNine.indexOf(this.id) + ''; 16 kotae.value = digit; //一つ目の数値 17 }; 18 } 19 for (var i = 0; i <= 9; i++) { 20 digitElements[i] = document.getElementById(zeroToNine[i]); 21 digitElements[i].onclick = function() { 22 // アラビア数字に変換 23 var digit2 = zeroToNine.indexOf(this.id) + ''; 24 kotae.value = digit2; //2つ目の数値 25 }; 26 } 27

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答5

0

許可された内容 なし。これは空要素です。

タグの省略 開始タグは必須。終了タグを記述してはならない。
input 要素 - HTML | MDN

textContentではなくて、valueを操作してみてください。

投稿2016/11/07 11:48

Lhankor_Mhy

総合スコア35869

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ojgtmaga

2016/11/07 12:21

ご回答本当にありがとうございます。 参考リンク確認しました。終了タグは記載しないのですね。 textContentではなくて、valueで操作してみましたが、テキストボックス上に表示できませんでした。 何かまだおかしいのでしょうか? もしよろしければ、ご教示お願いします。
Lhankor_Mhy

2016/11/07 12:35

> テキストボックス上に表示できませんでした その時のコードをご提示願います。 あと、できればエラーメッセージもお願いします。
ojgtmaga

2016/11/07 13:40

javascriptのファイルです。 var kotae = document.getElementById('ans'); var iti = document.getElementById('one'); var ni = document.getElementById('two'); var san = document.getElementById('three'); var yon = document.getElementById('four'); var go = document.getElementById('five'); var roku = document.getElementById('six'); var nana = document.getElementById('seven'); var hati = document.getElementById('eight'); var kyu = document.getElementById('nine'); var zyu = document.getElementById('zero'); var tasu = document.getElementById('plus'); var hiku = document.getElementById('minus'); var kakeru = document.getElementById('mul'); var waru = document.getElementById('div'); var ikoru = document.getElementById('equ'); iti.onclick = click1;//18列目 function click1(){ kotae.value = '1'; } htmlのファイルは</input>を抜いた以外そのままです。 エラーは、18列目に TypeError: Cannot set property 'onclick' of null(…) と出ています。
Lhankor_Mhy

2016/11/08 00:39

当方では、そのコードで動作します。 エラーメッセージを見ると、3つぐらい可能性が考えられます。 ・javascriptを読み込んでいる場所が早すぎる。 ・var iti = document.getElementById('one'); あたりに問題。 ・<button id="one" > 1 </button> あたりに問題。
guest

0

ベストアンサー

calculator.js / eval-calculation.js

趣味で作ってみましたが、考えるべき点がかなりある為、初心者が始める課題としては難易度が高いように感じました(GitHubのリンク先のコメント欄にjsfiddleのサンプルがありますので簡易的に実行したい場合はそちらからどうぞ)。

以降、基本的な部分、躓きやすい部分を解説しますが、理解が難しいと感じるようであれば、現在の「電卓を作る」という課題は保留してJavaScriptの基礎勉強から始める事をお勧めします。

演算結果をクリアできない問題

「一切htmlには手を加えず」という事ですが、質問文にあるHTMLをそのまま利用する形ですと電卓によくある [C] キーがない為、計算ミスしたらページを再読み込みするまで演算結果をクリア出来ないという問題があります。

小さなコードから作り始めて合体する

何にでもいえる事ですが、まずは小さな事から始めましょう。
HTML文書上に出力するというのは置いておき、次のような算術式の文字列を与えて演算結果を返す汎用的な関数を作成してみましょう。

JavaScript

1calc('1 + 3 * 4'); // 13 2calc('-3 * 2'); // -6 3calc('10 / 2 + 4'); // 9

上の calc() 関数を作るのが難しいと感じるようであれば、calc('1 + 2') のような単純な式から解析できるようにして徐々に難しい式を解析できるように発展させてみましょう。

演算子の優先順位

おそらく、関数 calc() を作る上でこれが最も難しいと思われる部分です。次の計算式の演算結果を考えてみて下さい。

JavaScript

12 * 3 + 5 * 6

算数上の答えは「36」です。
*+ よりも優先順位が高い為、先に掛け算で演算してから加算を実行します。
掛け算を優先して処理をするというのが曲者で何も考えずに作ると次のようにコーディングしたくなるでしょう。

JavaScript

1((2 * 3) + 5) * 6

演算結果は「66」ですが、正しい答えではありません。
これを解決する為には算術式から「掛け算」「割り算」を優先して見つけて先に処理する必要があります。
手法としては次の2通りが考えられます。

  1. String.prototype.replace で第二引数のコールバック関数を指定する
  2. RegExp.prototype.exec で算術式文字列をマッチさせた後に置換し、マッチしなくなるまで続ける

参考までに、私が先のコードで採用したのは 1. です。

DOM Events

要素ノードを一つ一つ指定する手間を省きたいようですが、そういう場合は「親要素(もしくは祖先要素)」に対して click イベントを割り当て、event.target でクリックされた要素を参照して判定する方法がお勧めです。

基礎的な勉強

初めにも書きましたが、初心者が始める課題としては難易度が高いと思います。
今までに解説した内容の理解が困難であれば、MDNのチュートリアルから初めてDOMの基礎的な部分も学ぶ流れが良いと思います。

更新履歴

  • 2016/11/09 04:36 calculator.js を ver.0.9.4 に更新しました。
    ・数字を最後に入力した時に演算結果を表示するようにした
    ・計算式のテキストボックスでキーボード入力できるようにした
    ・適用対象を <form id="calc-form"> から <form class="calc-form"> に変更し、複数設置できるようにした
    ・内部的に整数演算する事で「0.6*3 === 1.8」と計算できるようにした(IEEE754の丸め誤差対策)
  • 2016/11/11 14:09 calculator.js を ver.0.9.5 に更新しました(更新履歴はGitHub/jsfiddleのリンク先を参照)。

Re: ojgtmaga さん

投稿2016/11/08 08:53

編集2016/11/11 05:14
think49

総合スコア18156

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ojgtmaga

2016/11/08 13:46

丁寧な回答ありがとうございます。 電卓が初心者には難易度が高いことがよくわかりました。 もっと勉強が必要のようです。 think49さんが作った電卓が難しいのは、ソースを見てよくわかりました。 一応、今回私が、htmlのソースに基づいて作って見たかった電卓は、一桁の計算の電卓でした。またCボタンは作ってないので、下記の1~4の流れで終了と考えていました。 1.1~9の数字をおし、□の部分に表示 2.+-*/のどれかを押す 3.1~9の数字をおし、□の部分に表示 4.答えを□の部分に表示 です。 このような非常に単純な電卓なら初心者にも分かるかなと思いましたが、難しいのでしょうか?
think49

2016/11/08 19:42

To: ojgtmaga さん その流れなら「2 + 3 = 5」のようになりますが、「2 + 3 + 4」のように続かないなら簡単な処理で済むと思います。 数字を一桁にする事は「[1] キーを押す -> [2] キーを押す」に対して入力文字列を連結して「12」を作る手段が分からないのであれば有効ですが、それほど難しい処理ではありません。 いずれにしても「習うより慣れよ」ですのでコードを書き始めて分からない部分が出来てから質問した方が良いと思います。 現状ですとコードを書く前に「これは難しいですか?」と聞いている状況です。
ojgtmaga

2016/11/09 04:30

ご回答ありがとうございます。 一応、naomi3 さんに教えて頂いたソースに基づいて考えています。 それを実行すると、数字(1を押したら1と表示できています。)つまり、1の段階です。 しかしながら、わからないのは、この次の段階です。 1回目の数値を入力し、+-*/を押してから2回目の数値を入力。そして、=を押すため、 1回目の数値入力の後は、+-*/の処理を考えるべきか。 それとも2回目に入力される数値を先に作るのか考えるかです。 また、1つ目の数字をdigit とした場合、2つ目の数字のdigit2が必要になると思いました。 そのための方法は、どうすれば良いのかです。一応考えたソースは追記に貼っておきました。 もう一度for文を繰り返し、2回目は、var digitをvar digit2に変えましたが、動きませんでした。 今まで作ったことがある電卓だと、数字を入力するテキストボックスを2つ作り、数字を両方に入力します。そして+-*/のいずれかを押すことで計算できるというものでした。そのため、一度入力した数値を書き換えることがなかったのです... できれば、答えを知り、その中のコードを変えていくことによって、そのコードがどのような働きをしているのか学んでいきたいです。よろしければ、ご教示お願いします。
think49

2016/11/09 07:22

To: ojgtmaga さん 追記されたコードを元にjsfiddleにコードをUPしました。 https://jsfiddle.net/53mg3n27/ > 1回目の数値入力の後は、+-*/の処理を考えるべきか。 > それとも2回目に入力される数値を先に作るのか考えるかです。 その2択なら [+--*] が入力される処理を考えます。 ただ、まあ何度も言っていますが、私なら次のような関数を作ってから入力処理を実装します。 function calc (number1, number2, operator) {} var kotae = calc(1, 2, '+'); console.log(kotae); // 3 kotae = calc(3, 2, '-'); console.log(kotae); // 1 > もう一度for文を繰り返し、2回目は、var digitをvar digit2に変えましたが、動きませんでした。 digitElements[i].onclick を上書きしているように見えますが、このコードが何をしているか理解していますか。 このコードを実行すると digit に代入される処理は働きません。digit2 だけに代入処理が働きます。 console.logに出力するようにしてみましたが、やはり digit2 しか出力されませんでした。 https://jsfiddle.net/53mg3n27/ 例えば、下記コードは理解できるでしょうか。 var a = 1; a = 2; console.log(a); // 2 それと同じことをやっています。
ojgtmaga

2016/11/09 09:15

ご回答ありがとうございます。つまり、例えば1をクリックした時に1を表示するというのをdigitとdigit2で同じことをやっているから、後に書いたdigit2が実施され、digitが実施されていないということですね。 アップしていただいた、コードを見てよくわかりました。 後、横よく考えた変更点ですが、一桁の計算の場合は、kotae.value += digit;ではなく、kotae.value = digit;で良かったです。訂正します。 function calc (number1, number2, operator) {} var kotae = calc(1, 2, '+'); console.log(kotae); // 3 を見ましたが、これを自分が作成しているjavascriptに基づくと、イコールボタンを押して答えがkotaeのところに表示させると考えた場合、 ikoru.addEventListener('click', function calc(digit, number2, operator) { var answer1 =calc(digit, number2,'+'); kotae.value = answer1; var answer2 =calc(digit, number2,'-'); kotae.value = answer2; var answer3 =calc(digit, number2,'*'); kotae.value = answer3; var answer4 =calc(digit, number2,'/'); kotae.value = answer4; }); でよろしいのでしょうか? また、上では2つ目の数値はnumber2と書きましたが、その2つ目の数値を入手するコードは想像がつきませんでしたので、よろしければご教示お願いします。
think49

2016/11/10 04:44 編集

To: ojgtmaga さん また、代入処理を繰り返す失敗を犯していますので、前の教訓を生かしましょう。 やはり、この課題は保留して基礎からやり直した方が良いと思います。 簡単な if文, switch 文の使い方から初めて +, -, *, / 演算子の扱いを学び、ユーザ定義関数の作り方を習得すれば基本的な機能は出来ます。 最後にDOMを習得すればいいでしょう。 > その2つ目の数値を入手するコードは想像がつきませんでした 後々を考えるなら関数の引数として渡すのが望ましいですが、それが難しいようであればグローバル変数を使ってもいいでしょう。 コードの質向上は後でも出来るので、作り上げる事を優先していいかと。
ojgtmaga

2016/11/10 01:45

そうですね。 もう一度基礎からやり直したいと思います。 この度は、様々なご指摘ありがとうございました。 最後にやや後味が悪いので、もしよろしければ、今回の作りたかった電卓をthink49さんならどのように作るか教えて頂けないでしょうか。
think49

2016/11/11 05:21 編集

To: ojgtmaga さん 私のコードは親記事に「GitHubのリンク」を貼っていますのでそちらを参照して下さい。jsfiddleに動くサンプルがあります。 https://jsfiddle.net/vfqg6chs/4/ (※上記のjsfiddleのURLは2016/11/11 14:00現在の最新版 ver.0.9.5 のサンプルです。随時更新される為、最新版のリンクはGitHubから参照して下さい。) 計算式の評価関数は eval-calculation.js に分離した為、計算式の解析処理を見たい場合はそちらを参考にして下さい。
guest

0

「一切htmlには手を加えず」という縛りなので + - * / = は表示するための場所が無かったから非表示。

JavaScript

1let o = { v1: [], v2: [], f: null }, func, ans = document.getElementById( 'ans' ); 2ans.value = 0; 3func = ( v1, f, v2 ) => { 4 let res; 5 v1 = parseInt( v1, 10 ); 6 v2 = parseInt( v2, 10 ); 7 8 if ( '+' === f ) { 9 return v1 + v2; 10 } else if ( '-' === f ) { 11 return v1 - v2; 12 } else if ( '*' === f ) { 13 return v1 * v2; 14 } else if ( '/' === f ) { 15 if ( v2 === 0 ) { 16 return '/0 error'; 17 } 18 return v1 / v2; 19 } 20}; 21[].forEach.call( document.getElementsByTagName( 'button' ), n => { 22 n.addEventListener( 'click', e => { 23 let t = n.textContent.trim(), v, res; 24 if ( parseInt( t, 10 ) >= 0 ) { 25 v = ( !o.f ) ? o.v1 : o.v2; 26 v.push( t ); 27 ans.value = v.join( '' ); 28 } else { 29 if ( o.f && o.v1.length && o.v2.length ) { 30 res = func( o.v1.join( '' ), o.f, o.v2.join( '' ) ); 31 o.v1 = []; 32 o.v2 = []; 33 o.f = null; 34 if ( typeof res === 'string' ) { 35 alert( res ); 36 ans.value = 0; 37 return; 38 } 39 ans.value = res; 40 } 41 if ( '=' !== t ) { 42 if ( o.v1.length === 0 ) { 43 o.v1 = ( ans.value + '' ).split( '' ); 44 } 45 o.f = t; 46 } 47 } 48 }, false ); 49} ); 50```**動くサンプル:**[https://jsfiddle.net/yxmaLL2c/](https://jsfiddle.net/yxmaLL2c/)

投稿2016/11/07 17:44

kei344

総合スコア69366

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ojgtmaga

2016/11/08 03:08 編集

ご回答ありがとうございます。 まだまだ、初心者なため、分からない部分が多くありました。 また、よく分からない文法も多くありました。 例えば、let a = 1という形は知っているのですが、 let o = { v1: [], v2: [], f: null }という書き方はわかりませんでしたし、このfは何のことを指しているのか?など挙げれば様々でした。 kei334さんが書いてくれたコードは私には難しすぎたようです。 一応、今の私が実現したいことは、 1.1~9の数字をおし、□の部分に表示 2.+-*/のどれかを押す 3.1~9の数字をおし、□の部分に表示 4.答えを□の部分に表示 です。 最初は一桁の計算で考えていました。Cボタンはとりあえずは作ってないので、1~4の流れで終了です。 申し訳ないのですが、できるだけ初心者にもわかるようなコードで教えてもらうことは可能でしょうか?
kei344

2016/11/08 03:38

> 例えば、let a = 1という形は知っているのですが、 let o = { v1: [], v2: [], f: null }という書き方はわかりませんでしたし、 オブジェクトの中に配列を入れているだけですが、この記法がわからないということは入門書などをあまり読み進められていないのでしょうか。(それともそこに触れていない入門書だったのでしょうか・・・) Webの情報を読む前に、一度本屋で何冊か本を買って読むと今後の理解が進みます。とりあえず最初はわからないことのほうが多いと思いますが、そのうち腑に落ちることも多いはずなのでお勧めします。 JavaScript ならとりあえずこれを通読してみてください、お勧めです。 【JavaScript 第6版 : David Flanagan, 村上 列 : 本 : Amazon.co.jphttp://www.amazon.co.jp/dp/4873115736 【絶対に読んでおきたい、JavaScriptのおすすめ書籍7冊 - Qiita】 http://qiita.com/axross/items/1fc342c04aa88d48c713
ojgtmaga

2016/11/08 04:29

近くの図書館にJavaScript 第6版があったため、今日の帰りに借りに行きたいと思います。 配列はやったのですが、例えば、var array=[ , ]の形しか知りませんでした。 とりあえず、それを読みながら考えていきたいと思います。 最後にkei344さんなら、私が作りたかった電卓をどのように作りますでしょうか。 一桁の計算の電卓です。上記で示した流れで、一桁の計算で1~4の流れで終わる電卓なら二桁以上の計算や何回も足したり、かけたりできる電卓に比べて、ソースコードの入力が少なく導入に良いかなと思いました。 そのため、できれば、そのソースに基づいて、勉強していきたいです。 もしよろしければ、ご教示お願いします。
kei344

2016/11/08 04:43

> 配列はやったのですが、例えば、var array=[ , ]の形しか知りませんでした。 オブジェクトって書いてるのですが・・・。 > 私が作りたかった電卓をどのように作りますでしょうか。 上記のものでも一桁は可能ですよ。リンク先に動くサンプルがあるので、確認してみてください。 toutouさんの提示されているURLにも例があるので、それを参考にされてみてはいかがでしょうか。
ojgtmaga

2016/11/08 08:35 編集

確かにオブジェクトですね。間違えました。すみません。 色々と適切なご返答本当にありがとうございます。 kei334さんの作ったサンプルは、何回も繰り返し計算できますし、桁数も自由にできてると思います。 逆に一桁だけと制限してもできるのでしょうか(つまり、二桁は入力できないですし、計算も例えば1+1=2で終わりで、1+2-1*4みたいに繰り返し計算をすることは考えないということです)? 一桁だけから初めて、それから、二桁にする方法や何回も繰り返し計算できる方法を知っていきたいとおもってます。 もしよろしければ、ご教示お願いします。
kei344

2016/11/08 08:35

> 逆に一桁だけと制限してもできるのでしょうか どう逆なのかがわかりませんが、制限することは出来ると思いますよ。 > 一桁だけから初めて こだわる理由がまったくもってわかりませんが、数値が取得できたのなら足すところから始めればいいのでは?比較的わかりやすいコードを探してまねてやってみたらどうですか。
think49

2016/11/08 09:14 編集

To: kei344 さん jsfiddleのコードで「2 * 3 + 5 * 6」を計算すると「66」になりましたが、これは期待通りの結果でしょうか。 数式上の正答は「36」であり、Androidアプリ『Speed 電卓 Free』で試した結果も「36」でした。普通の電卓が手元になくて検証できないのが悔やまれますが…。 おそらく、「((2 * 3) + 5) * 6」の演算結果になっていると思うのですが、それが電卓の結果と一致するのかどうか…。
kei344

2016/11/08 09:21 編集

電卓との数値が合わないのはコードどおりです。割り算の計算も小数点がからむと実際の計算結果と異なることになります。どこまでするかな、と思って書いてみたというのがこの結果になります。 掛け算と割り算の順序を通常の計算と合わせるように書き直してみようかな・・・。 【演算子の優先順位 - Wikipedia】 [https://ja.wikipedia.org/wiki/%E6%BC%94%E7%AE%97%E5%AD%90%E3%81%AE%E5%84%AA%E5%85%88%E9%A0%86%E4%BD%8D#.E9.9B.BB.E5.8D.93](https://ja.wikipedia.org/wiki/%E6%BC%94%E7%AE%97%E5%AD%90%E3%81%AE%E5%84%AA%E5%85%88%E9%A0%86%E4%BD%8D#.E9.9B.BB.E5.8D.93) > 多くのいわゆる普通の電卓は、入力された順に計算する。 (そんなこと無い気がする)
Lhankor_Mhy

2016/11/08 10:00

横からすみません。 通常の電卓は入力された順に計算すると思います。 一般的な電卓は数式を保存できません。計算結果窓には前回の演算の結果が表示されており、演算子を押すことによってその結果を被演算数として逐次的に計算するのが一般的かと。 科学電卓やFP電卓のような、数式を保存しておける高級な電卓だと36を返すと思います。
kei344

2016/11/08 10:24

To: Lhankor_Mhyさん 補足ありがとうございます。確かに計算式の表示できない手元の電卓では逐次計算になりますね。確認してからコメントするべきでした、ありがとうございます。
think49

2016/11/08 10:29

To: kei344 さん、Lhankor_Mhy さん ありがとうございます。私自身が数式が表示される電卓に慣れきってしまって通常の電卓の感覚を忘れてしまっていました。 電卓で [+], [-], [*], [/] キーを押す度に逐次計算していた記憶はあるのですが、数式をキャッシュした計算結果だったかまでは確信が持てず、曖昧な指摘に…。 - 廉価版の電卓では「前方の数値から盲目的に計算する逐次計算方式」 - 高級な電卓では「数式をキャッシュして演算子の優先順位を考慮した計算をする全体計算方式」 というところのようですね(用語は感覚ベースで適当です)。
think49

2016/11/08 19:59

To: kei344 さん 別にバグらしき挙動を確認しましたので報告を。 初めに「-1」を入力すると画面には「1」と表示されます。 「-1 -3」は「-4」になりますが、「-1 * -3」も「-4」になりました。 - を入力した時に - 演算子と強制的に扱われて演算子が上書きされるようです。
Lhankor_Mhy

2016/11/09 00:05

たびたび横からすみませんが、一般的な電卓ですと"-"記号の意味的解釈をしないので、負号と減算演算子には別のキーが与えられています。
think49

2016/11/09 03:16 編集

To: Lhankor_Mhy さん 度々、ありがとうございます。 なんと…、負号と減算演算子が別々に定義されているとは盲点でした。 (調べてみたところ、[±] キーで符号反転するのが通常の電卓のようですね) 検証してみたところ、Androidアプリ『Speed 電卓 Free』では「[*] キー押下 -> [-] キー押下」の手順で [-] キー入力を受け付けず、Google標準のAndroidアプリ『電卓』では「-1 * -3 === 3」となりました。 Google標準のAndroidアプリ『電卓』では [-] キーが一つしかありませんが、「"-" が負号/減算演算子のどちらであるか」を文脈的に上手い具合に判断してくれるようです。 かくいう私も深く考えずにGoogleと同じように作ったのですが、まさかこれが標準の電卓とは違った実装だったとは…。
guest

0

前質問の回答でもあった イヌでもわかるJavaScript講座 - 電卓
ここらへんは見ましたでしょうか?

投稿2016/11/07 12:42

toutou

総合スコア2050

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

think49

2016/11/08 09:10

ご掲示のページ上で「2 * 3 + 5 * 6」を実行すると「66」になりましたが、電卓とはそういうものだったでしょうか…。 数式上は「2 * 3 + 5 * 6 === 36」ですが、ここでは「((2 * 3) + 5) * 6 == 66」を採用しているようです。
toutou

2016/11/08 09:44

電卓の性能によって多少違いが出るようです。Windowsについてる電卓でやったところ66になりました。もっといいのを作りたかったら、またそれについて質問があるかと。提示してるコードもいまいちですし、前の質問でここらへんをお勧めされてたので、読んだ上での質問なのかなと思い確認したかったのです。
think49

2016/11/08 10:31

To: toutou さん すみません、別スレでも同様の指摘を頂きました。 そういう電卓もあるという事で間違いではないのですね。 質問者さんは簡単なコードから始めるようですので、この方法でも問題はなさそうです。
guest

0

HTML

1 <input id="ans" size="20" readonly></input><br> 2 <button name="digit" value="1" id="1" > 1 </button> 3 <button name="digit" value="2" id="2" > 2 </button> 4 <button name="digit" value="3" id="3" > 3 </button> 5 <button name="digit" value="4" id="4" > 4 </button> 6 <button name="digit" value="5" id="5" > 5 </button><br> 7 <button name="digit" value="6" id="6" > 6 </button> 8 <button name="digit" value="7" id="7"> 7 </button> 9 <button name="digit" value="8" id="8"> 8 </button> 10 <button name="digit" value="9" id="9"> 9 </button> 11 <button name="digit" value="0" id="0"> 0 </button><br> 12 <button id="plus"> + </button> 13 <button id="minus"> - </button> 14 <button id="mul"> * </button> 15 <button id="div" > / </button> 16 <button id="equ"> = </button>

JavaScript

1 var kotae = document.getElementById('ans'); 2 var digits = document.getElementsByName('digit'); // 配列になる 3 var tasu = document.getElementById('plus'); 4 var hiku = document.getElementById('minus'); 5 var kakeru = document.getElementById('mul'); 6 var waru = document.getElementById('div'); 7 var ikoru = document.getElementById('equ'); 8 9 for (var i = 0; i <= 9; i++) { 10 digits[i].onclick = function() { 11 kotae.value += this.value; 12 }; 13 }

数字のキーはこのようにすると、コードを短縮でき、間違えにくくなります。
2桁以上にも対応しています。

これでどうですか。

JavaScript

1 var kotae = document.getElementById('ans'); 2 var zeroToNine = ["zero", "one", "two", "three", "four", 3 "five", "six", "seven", "eight", "nine"]; 4 var digitElements = new Array(10); 5 var tasu = document.getElementById('plus'); 6 var hiku = document.getElementById('minus'); 7 var kakeru = document.getElementById('mul'); 8 var waru = document.getElementById('div'); 9 var ikoru = document.getElementById('equ'); 10 11 for (var i = 0; i <= 9; i++) { 12 digitElements[i] = document.getElementById(zeroToNine[i]); 13 digitElements[i].onclick = function() { 14 // アラビア数字に変換 15 var digit = zeroToNine.indexOf(this.id) + ''; 16 kotae.value += digit; 17 }; 18 }

私の答えはこうです。よくある状態遷移です。
[AC]ボタンはご自身で実装してみてください。

JavaScript

1 var kotae = document.getElementById('ans'); 2 3 var zeroToNine = ["zero", "one", "two", "three", "four", 4 "five", "six", "seven", "eight", "nine"]; 5 var digitButtons = new Array(10); 6 7 // 演算子ボタン 8 var operators = ["plus", "minus", "mul", "div"]; 9 var operatorButtons = new Array(operators.length); 10 11 var calculatingButton = document.getElementById('equ'); 12 13 // 状態定数 14 var STATE = { 15 INITIAL : 0, 16 DIGIT_BUTTON_PRESSED_AT_FIRST : 1, 17 OPERATOR_BUTTON_PRESSED : 2, 18 DIGIT_BUTTON_PRESSED_AT_SECOND : 3, 19 CALCULATING_BUTTON_PRESSED : 4 20 }; 21 // 状態変数 22 var state = STATE.INITIAL; 23 24 // 数値記憶用 25 var memory = 0; 26 // 押された演算子 27 var pressedOperator = ''; 28 29 for (var i = 0; i <= 9; i++) { 30 digitButtons[i] = document.getElementById(zeroToNine[i]); 31 digitButtons[i].onclick = function() { 32 // アラビア数字に変換 33 var digit = zeroToNine.indexOf(this.id) + ''; 34 35 switch (state) { 36 case STATE.INITIAL: 37 case STATE.DIGIT_BUTTON_PRESSED_AT_FIRST: 38 kotae.value += digit; 39 state = STATE.DIGIT_BUTTON_PRESSED_AT_FIRST; 40 break; 41 42 case STATE.OPERATOR_BUTTON_PRESSED: 43 kotae.value = ''; 44 // noBreak; 45 case STATE.DIGIT_BUTTON_PRESSED_AT_SECOND: 46 kotae.value += digit; 47 state = STATE.DIGIT_BUTTON_PRESSED_AT_SECOND; 48 break; 49 50 } 51 }; 52 } 53 54 for (i = 0; i < operatorButtons.length; i++) { 55 operatorButtons[i] = document.getElementById(operators[i]); 56 operatorButtons[i].onclick = function() { 57 switch (state) { 58 case STATE.DIGIT_BUTTON_PRESSED_AT_FIRST: 59 case STATE.CALCULATING_BUTTON_PRESSED: 60 pressedOperator = this.id; 61 memory = parseInt(kotae.value, 10); 62 state = STATE.OPERATOR_BUTTON_PRESSED; 63 break; 64 } 65 }; 66 } 67 68 calculatingButton.onclick = function() { 69 if (state === STATE.DIGIT_BUTTON_PRESSED_AT_SECOND) { 70 var operand = parseInt(kotae.value, 10); 71 72 switch (pressedOperator) { 73 case "plus": 74 kotae.value = memory + operand; 75 break; 76 77 case "minus": 78 kotae.value = memory - operand; 79 break; 80 81 case "mul": 82 kotae.value = memory * operand; 83 break; 84 85 case "div": 86 kotae.value = memory / operand; 87 break; 88 89 } 90 91 state = STATE.CALCULATING_BUTTON_PRESSED; 92 } 93 };

投稿2016/11/07 12:33

編集2016/11/10 13:45
naomi3

総合スコア1105

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ojgtmaga

2016/11/07 13:46

ご回答ありがとうございます。 だいぶコードが見やすくなり、驚いています。 今回htmlにdigitを足すことによって、javascriptのコードを短くできてると思います。 質問なのですが、一切htmlには手を加えず、javascriptだけを編集して、同じようなことができるのでしょうか? もしできるのであれば、どのようにやるのかご教示お願いできますでしょうか。
ojgtmaga

2016/11/07 15:07

本当によくわかりました。ありがとうございます。特にjavascriptで複数の DOMを取得する方法がわからなかったのですが、よくわかりました。 重ね重ね申し訳ないですが、これが最後の質問です。もし可能であれば、ご教示お願いします。 現在、一桁の計算ができる電卓を考えているのですが、詰まっています。 一応考えているのが、 1.1~9の数字をおし、□の部分に表示 2.+-*/のどれかを押す 3.1~9の数字をおし、□の部分に表示 4.答えを□の部分に表示 本当に申し訳ないのですが、もしよろしければ、ご教示お願いします。 一応考えて見たことは、 ・+-*/を1~9の数字と同じように var calculate = ["plus", "minus", "mul","div"]:のようにできないか・数字を二回入力するため、1回目の数字をどのようにキープしておくか。 です。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問