Javascriptで電卓を作ろう　第2回　四則演算をやってみよう。

スタイルが出来上がったので、次は計算をしていきたいと思います。
[第一回のHTMLとCSSを作る記事は、こちら](https://qiita.com/rikimaru914/items/3412df78570b48b25858)

# 目次
[第1回 HTMLとCSSでボタンを横並びで配置しよう](https://qiita.com/rikimaru914/items/3412df78570b48b25858)

- HTMLのマークアップ
- CSS

[第2回　四則演算をやってみよう（今回の記事はここ）](https://qiita.com/rikimaru914/items/a30d83c43a4eb14ba999)

- Javascriptで四則演算
- 6)打った数字をコンソールに出力させよう。
- 7)打った数字と記号を変数に格納しよう。
- 8)計算結果を出力させよう。
- 8-1）「＝」を押した時の処理
- 8-2) 計算結果と計算途中を、計算結果の画面に表示させよう。

[第3回　連続で演算記号や小数点が押された場合の不具合処理](https://qiita.com/rikimaru914/items/8df2124165afd036b922)

- 最初に「＋　÷　－　×　＝」が押せないようにする。
- 二回連続で計算できるようにしたい。
- Cボタン（リセットボタン）を押した時の処理
- BS(バックスペース）ボタンを使えるようにする

[第4回　小数点を正しく入力できるように改善しよう](https://qiita.com/rikimaru914/items/61154567fa02f1d7a156)

- 12.12.や12..12のように小数点を間違って入力できてしまう。
- 電卓と同じように「.4」と入力したら0.4としたい。

[第5回　演算記号を連続して押した時の不具合を直そう](https://qiita.com/rikimaru914/items/21b3e4532f0de41db9a6)

[第6回　バックスペースを押した時の不具合を直そう。](https://qiita.com/rikimaru914/items/0a97bfa685620f16cd5b)

[第7回　「4 ÷ 3 = 1.33333333333333333」の表示桁数を10桁にしたい](https://qiita.com/rikimaru914/items/c3f23aa65f4be780d6ff)

[第8回　「電卓と同じ表示画面を目指そう](https://qiita.com/rikimaru914/items/b4076b2673014034076c)

前回のHTML

```html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>電卓</title>
    <link rel="stylesheet" href="style.css">
  </head>
  <body>
    <div class = "container">
<!--      計算結果を出力する場所-->
      <div id = "output_total" class="output ">0</div>
<!--      計算過程を出力する -->
      <div id = "output_sub" class="output active">0</div>
<!--      ボタンを配置する場所-->
      <div class = 'input'>
          <section class = 'row'>
            <div id = "clear">C</div>
            <div class = "num_bth"></div>
            <div class = "num_bth" id="bs">BS</div>       
            <div class = "num_bth " data-index-id= '/'>÷</div>
          </section>
          <section class = 'row'>
            <div class = "num_bth " data-index-id = 9 >9</div>
            <div class = "num_bth " data-index-id = 8 >8</div>
            <div class = "num_bth " data-index-id = 7 >7</div>
            <div class = "num_bth " data-index-id = '*'>×</div>
          </section>
          <section class = 'row'>
            <div class = "num_bth " data-index-id = 6 >6</div>
            <div class = "num_bth " data-index-id = 5 >5</div>
            <div class = "num_bth " data-index-id = 4 >4</div>
            <div class = "num_bth " data-index-id = '-'>－</div>     
          </section>
          <section class = 'row'>
            <div class = "num_bth " data-index-id = 3 >3</div>
            <div class = "num_bth " data-index-id = 2 >2</div>
            <div class = "num_bth " data-index-id = 1 >1</div>
            <div class = "num_bth " data-index-id = '+'>+</div>
          </section>
          <section class = 'row'>
            <div class = "num_bth" data-index-id = 00 >00</div>
            <div class = "num_bth" data-index-id = 0 >0</div>
            <div class = "num_bth" data-index-id = . >.</div>
            <div id = 'equal_btn'>=</div>       
          </section>        
      </div>
    </div>
    <script src="script.js"></script>
  </body>
</html>

```


#Javascript処理
6)打った数字をコンソールに出力させよう。
例1）【ボツ】　一応、打った番号は出力されるが、同じコードの繰り返しになる書き方は却下。

```javascript
'use strict'
{
  const num_bth = document.getElementsByClassName('num_bth');
  num_bth[3].addEventListener('click', () => {
    console.log(num_bth[3].textContent);
  });//9をクリックすると9が出力
  
  num_bth[4].addEventListener('click', () => {
    console.log(num_bth[4].textContent);
  }) ///8をクリックすると9が出力
  
  //以下続く
    
}
```
これでもコンソールにクリックした数字は出力できますが、こんな書き方をしてたら、先生に怒られてしまいそうです。

例2)【ボツ】同じコードの繰り返しをやめるため、getElementsByClassNameとforを使ってみる

```javascript
  const num_bth = document.getElementsByClassName('num_bth'); 
    for(let i = 0; i < num_bth.length ; i++) {
      num_bth[i].addEventListener('click', () => {
        console.log(num_bth[i].textContent);
      }) //click
    }//for
```

これで同じコードを繰り返して書かなくてもクリックしたキーの値をコンソールに出力できました。

例3)【ボツ】もう少し短く書くため、querySelectorAllとforEachを使う

```javascript
  const num_bth = document.querySelectorAll('.num_bth');
  num_bth.forEach(index => {
    index.addEventListener('click', () => {
      console.log(index.textContent);
    }) //click
  })//forEach
//123456890+-×÷が出力される
```
数字はうまく出力されますが、この方法だと「÷」を押すとが「÷」出力され、「×」を押すと「×」が出力される。。「/」や「*」が出力されないと計算できない。

ちなみにforEachは配列に対して行うので、複数あるものなら使えるわけではなかった。以下だとエラーになります。

```javascript
  const num_bth = document.getElementsByClassName('num_bth');
  num_bth.forEach(index => {
    index.addEventListener('click', () => {
      console.log(index.textContent);
    }) //click
  })//forEach
×以下のエラメッセージが表示される。
Uncaught TypeError: num_bth.forEach is not a function
```

例4)【採用】
カスタムdata属性を使う。

忘れてたら、
[詳解JavaScript DOM編 #06 カスタムデータ属性を扱ってみよう　参照](https://dotinstall.com/lessons/basic_javascript_dom/48006)

```javascript
  const num_bth = document.querySelectorAll('.num_bth');
  num_bth.forEach(index => {
    index.addEventListener('click', () => {
      console.log(index.dataset.indexId)
    }) //click   
  })//forEach 
//123456890+-*/が出力される
  
```
7)打った数字と記号を変数に格納しよう。

```javascript
  const num_bth = document.querySelectorAll('.num_bth');
  let total = 0;//計算式を表す変数 
  num_bth.forEach(index => {
    index.addEventListener('click', () => {
      console.log(index.dataset.indexId)
      total += index.dataset.indexId;  
      console.log(total);  
    }) //click   
  })//forEach
```
12+3をクリックするとコンソールにこの以下のように出力される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320736/ac7c7a70-3238-69c2-ec9f-0ad2ecb377f1.png)

【失敗例】

```javascript
  const num_bth = document.querySelectorAll('.num_bth');
  let total;//計算式を表す変数 
  
  num_bth.forEach(index => {
    index.addEventListener('click', () => {
      console.log(index.dataset.indexId)
        total += index.dataset.indexId;     
      console.log(total);  
    }) //click   
  })//forEach
```
ボタンを押す前は、変数には数字がないため、undefinedとなってしまう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320736/9922486d-164f-e803-171c-d927818900d3.png)

- 8)計算結果を出力させよう。
【失敗例】

```javascript
'use strict'
{
  const num_bth = document.querySelectorAll('.num_bth');
  let total = 0;//計算式を表す変数 
  
//  //数字や記号のボタンを押した時
  num_bth.forEach(index => {
    index.addEventListener('click', () => {
      console.log(index.dataset.indexId)
        total += index.dataset.indexId;     
      console.log(total);  
    }) //click   
  })//forEach
  
  //イコールを押した時
  const equal_btn = document.getElementById('equal_btn');
  equal_btn.addEventListener('click',() =>{
    console.log(eval(total));
  });
  
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320736/4897d524-4964-c8b6-7690-fe99363d71d0.png)
※
eval() は文字列として表された JavaScript コードを式として評価する関数。
0が付いていると計算ができない。
最初にクリックした時と、二番目の数字がクリックされた時で処理を変える。
【成功例】

```javascript
'use strict'
{
  const num_bth = document.querySelectorAll('.num_bth');
  let total = 0;//計算式を表す変数 
  
//  //数字や記号のボタンを押した時
  num_bth.forEach(index => {
    index.addEventListener('click', () => {
      console.log(index.dataset.indexId)
      if(total ===0) {
        total = index.dataset.indexId;  
      }else{
        total += index.dataset.indexId;
      }      
      console.log(total);  
    }) //click   
  })//forEach
  
  //イコールを押した時
  const equal_btn = document.getElementById('equal_btn');
  equal_btn.addEventListener('click',() =>{
    console.log(eval(total));
  });
  
}
```
12+3=15がコンソールに出力できた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320736/cd380883-d61e-cfbb-ec15-043b690d662d.png)

8-2) 計算結果と計算途中を、電卓の画面に表示させよう。

```javascript
'use strict'
{
  const num_bth = document.querySelectorAll('.num_bth');
  let output_sub = document.getElementById('output_sub');//計算結果を表示する場所
  const output_total = document.getElementById('output_total');//計算過程を表示する場所
  let total = 0;//計算式を表す変数 
  
//  //数字や記号のボタンを押した時
  num_bth.forEach(index => {
    index.addEventListener('click', () => {
      console.log(index.dataset.indexId)
      if(total ===0) {
        total = index.dataset.indexId;  
      }else{
        total += index.dataset.indexId;
      }      
      output_sub.textContent = total;
    }) //click   
  })//forEach
  
  //イコールを押した時
  const equal_btn = document.getElementById('equal_btn');
  equal_btn.addEventListener('click',() =>{
    console.log(eval(total));
    output_total.textContent = eval(total);
  });
  
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320736/858ff87e-65cd-cc69-704d-e6a930136cbb.png)
計算結果が出力できた。

#現状の問題点
レベル1はとりあえず計算結果を出力できるまで、ということで、ここまで。

レベル2では、以下の現状の問題点を一つずつ直していきたいと思います。

- 最初に「＋　÷　－　＝　.」が押せてしまう。
- 最初に0を連続で押せてしまう。
- 一度間違えると、全てやり直し（BSボタンを使えるようにしよう）
- 一度計算をやると、次の計算をするときに、ブラウザを読み込みなおさないといけない（Cボタンを使えるようにしよう）
- 12.12.や12..12のように小数点を正しくなく入力できてしまう。
- 割り算等で小数点以下が異様に長い。
- 記号ボタン（＋×÷-)を連続で押せてしまい、計算ができない。（連続で押した場合は、最後に押した記号ボタンが採用されるようにしたい。
- 電卓と同じように「.4」と入力したら0.4としたい。