Javascript UI 计算器

Javascript UI Calculator

我正在尝试制作一个带有 HTML 和 Javascript 用户界面的计算器。我已经修复了很多错误,但仍然存在以下问题:如果第二个运算符超过一位数,则答案错误,并且除法不起作用。我是新手,我知道我的代码效率低下而且 300 行太长了,但是有人可以逗我开心并解释我的错误吗?

var resultline_str = " ";
   var multidigit = 0
   var space = 0
   var operating = [];
   
   function type1(){
    resultline_str += " 1";
    document.getElementById('result').innerHTML = resultline_str;
    if(multidigit === 0){
     operating.push(1);
     multidigit = 1;
    }else{
     if(space === 0){
      var n = operating[0]
      n = operating[0].toString();
      n += '1';
      n = parseInt(n);
      operating[0] = n;
     }else{
      var n = operating[2]
      n = operating[2].toString();
      n += '1';
      n = parseInt(n);
      operating[2] = n;
     };
    };
   };
   
   function type2(){
    resultline_str += " 2";
    document.getElementById('result').innerHTML = resultline_str;
    if(multidigit === 0){
     operating.push(2);
     multidigit = 1;
    }else{
     if(space === 0){
      var n = operating[0]
      n = operating[0].toString();
      n += '2';
      n = parseInt(n);
      operating[0] = n;
     }else{
      var n = operating[2]
      n = operating[2].toString();
      n += '2';
      n = parseInt(n);
      operating[2] = n;
     };
    };
   };
   
   function type3(){
    resultline_str += " 3";
    document.getElementById('result').innerHTML = resultline_str;
    if(multidigit === 0){
     operating.push(3);
     multidigit = 1;
    }else{
     if(space === 0){
      var n = operating[0]
      n = operating[0].toString();
      n += '3';
      n = parseInt(n);
      operating[0] = n;
     }else{
      var n = operating[2]
      n = operating[2].toString();
      n += '3';
      n = parseInt(n);
      operating[2] = n;
     };
    };
   };
   
   function type4(){
    resultline_str += " 4";
    document.getElementById('result').innerHTML = resultline_str;
    if(multidigit === 0){
     operating.push(4);
     multidigit = 1;
    }else{
     if(space === 0){
      var n = operating[0]
      n = operating[0].toString();
      n += '4';
      n = parseInt(n);
      operating[0] = n;
     }else{
      var n = operating[2]
      n = operating[2].toString();
      n += '4';
      n = parseInt(n);
      operating[2] = n;
     };
    };
   };
   
   function type5(){
    resultline_str += " 5";
    document.getElementById('result').innerHTML = resultline_str;
    if(multidigit === 0){
     operating.push(5);
     multidigit = 1;
    }else{
     if(space === 0){
      var n = operating[0]
      n = operating[0].toString();
      n += '5';
      n = parseInt(n);
      operating[0] = n;
     }else{
      var n = operating[2]
      n = operating[2].toString();
      n += '5';
      n = parseInt(n);
      operating[2] = n;
     };
    };
   };
   
   function type6(){
    resultline_str += " 6";
    document.getElementById('result').innerHTML = resultline_str;
    if(multidigit === 0){
     operating.push(6);
     multidigit = 1;
    }else{
     if(space === 0){
      var n = operating[0]
      n = operating[0].toString();
      n += '6';
      n = parseInt(n);
      operating[0] = n;
     }else{
      var n = operating[2]
      n = operating[2].toString();
      n += '6';
      n = parseInt(n);
      operating[2] = n;
     };
    };
   };
   
   function type7(){
    resultline_str += " 7";
    document.getElementById('result').innerHTML = resultline_str;
    if(multidigit === 0){
     operating.push(7);
     multidigit = 1;
    }else{
     if(space === 0){
      var n = operating[0]
      n = operating[0].toString();
      n += '7';
      n = parseInt(n);
      operating[0] = n;
     }else{
      var n = operating[2]
      n = operating[2].toString();
      n += '7';
      n = parseInt(n);
      operating[2] = n;
     };
    };
   };
   
   function type8(){
    resultline_str += " 8";
    document.getElementById('result').innerHTML = resultline_str;
    if(multidigit === 0){
     operating.push(8);
     multidigit = 1;
    }else{
     if(space === 0){
      var n = operating[0]
      n = operating[0].toString();
      n += '8';
      n = parseInt(n);
      operating[0] = n;
     }else{
      var n = operating[2]
      n = operating[2].toString();
      n += '8';
      n = parseInt(n);
      operating[2] = n;
     };
    };
   };
   function type9(){
    resultline_str += " 9";
    document.getElementById('result').innerHTML = resultline_str;
    if(multidigit === 0){
     operating.push(9);
     multidigit = 1;
    }else{
     if(space === 0){
      var n = operating[0]
      n = operating[0].toString();
      n += '9';
      n = parseInt(n);
      operating[0] = n;
     }else{
      var n = operating[2]
      n = operating[2].toString();
      n += '9';
      n = parseInt(n);
      operating[2] = n;
     };
    };
   };
   function type_plus(){
    resultline_str += " +";
    document.getElementById('result').innerHTML = resultline_str;
    operating.push('+');
    multidigit = 0;
    place = 2;
   };
   
   function type_minus(){
    resultline_str += " -";
    document.getElementById('result').innerHTML = resultline_str;
    operating.push('-');
    multidigit = 0;
    place = 2;
   };
   
   
   function equals(){
    if(operating.length != 3){
     document.getElementById('result').innerHTML = 'Error';
     multidigit = 0;
     place = 0;
     return;
    }else{
     if(operating[1] === '+'){
      resultline_str = resultline_str + '<br/>' + (parseInt(operating[0]) + parseInt(operating[2])) + '<br/>';
     }else if(operating[1] === '-'){
      resultline_str = resultline_str + '<br/>' + (parseInt(operating[0]) - parseInt(operating[2])) + '<br/>';
     }else if(operating[1] === '*'){
      resultline_str = resultline_str + '<br/>' + (parseInt(operating[0]) * parseInt(operating[2])) + '<br/>';
     }else if(operating[1] === '/'){
      resultline_str = resultline_str + '<br/>' + (parseInt(operating[0]) / parseInt(operating[2])) + '<br/>';
     };
    };
    document.getElementById('result').innerHTML = resultline_str;
    operating = [];
    multidigit = 0;
    place = 0;
   };
   
   function clear_line(){
    resultline_str = " ";
    document.getElementById('result').innerHTML = resultline_str;
    operating = [];
    multidigit = 0;
    place = 0;
   };
   
   function times(){
    resultline_str += " *";
    document.getElementById('result').innerHTML = resultline_str;
    operating.push('*');
    multidigit = 0;
    place = 2;
   };
   
   function divide(){
    resultline_str += " /";
    document.getElementById('result').innerHTML = resultline_str;
    operating.push('-');
    multidigit = 0;
    place = 2;
   };
body{
    background-color:lightblue;
   }
   #head{
    background-color:blue;
    color:white;
    padding:10px;
    margin:10 auto;
    text-align:center;
    font-size:20px;
    font-family:courier;
    border:5px solid grey;
   }
   #grid{
    height:510px;
    width:260px;
    background-color:blue;
    color:white;
    border-collapse:collapse;
    border:10px solid black;
    float:left;
    margin-right:10px;
    
   }
   td{
    padding:30px;
    font-size:40px;
    size:400%;
    font-family:courier;
    font-weight:bold;
   }
   #result{
    float:right;
    height:525px;
    width:950px;
    background-color:white;
    border:2px solid black;
    text-align:right;
    font-size:45px;
    font-family:courier;
    font-weight:strong;
   }
<div id="head">
   <h1>Calculator<h1>
  </div>
  <div id="grid">
  
  <!-- calculator buttons -->
  <table>
   <tr>
    <td id="1" onclick='type1()'>1</td>
    <td id="2" onclick='type2()'>2</td>
    <td id="3" onclick='type3()'>3</td>
   </tr>
   <tr>
    <td id="4" onclick='type4()'>4</td>
    <td id="5" onclick='type5()'>5</td>
    <td id="6" onclick='type6()'>6</td>
   </tr>
   <tr>
    <td id="7" onclick='type7()'>7</td>
    <td id="8" onclick='type8()'>8</td>
    <td id="9" onclick='type9()'>9</td>
   </tr>
   <tr>
    <td id="=" onclick='equals()'>=</td>
    <td id="+" onclick='type_plus()'>+</td>
    <td id="-" onclick='type_minus()'>-</td>
   </tr>
   <tr>
    <td id="times" onclick='times()'>X</td>
    <td id="clear" onclick='clear_line()'>C</td>
    <td id="divide" onclick='divide()'>%</td>
   </tr>
  </table>
  </div>
<div id="result">
  <b></b>
  </div>

根据经验,您应该创建函数以避免重复代码。您的 table 应如下所示,并调用相同的函数来输入数字:

<div id="head">
        <h1>Calculator
            <h1>
    </div>
    <div id="grid">

        <!-- calculator buttons -->
        <table>
            <tr>
                <td id="1" onclick='typeNumber(1)'>1</td>
                <td id="2" onclick='typeNumber(2)'>2</td>
                <td id="3" onclick='typeNumber(3)'>3</td>
            </tr>
            <tr>
                <td id="4" onclick='typeNumber(4)'>4</td>
                <td id="5" onclick='typeNumber(5)'>5</td>
                <td id="6" onclick='typeNumber(6)'>6</td>
            </tr>
            <tr>
                <td id="7" onclick='typeNumber(7)'>7</td>
                <td id="8" onclick='typeNumber(8)'>8</td>
                <td id="9" onclick='typeNumber(9)'>9</td>
            </tr>
            <tr>
                <td id="=" onclick='equals()'>=</td>
                <td id="+" onclick='type_plus()'>+</td>
                <td id="-" onclick='type_minus()'>-</td>
            </tr>
            <tr>
                <td id="times" onclick='times()'>X</td>
                <td id="clear" onclick='clear_line()'>C</td>
                <td id="divide" onclick='divide()'>%</td>
            </tr>
        </table>
    </div>
    <div id="result">
        <b></b>
    </div>
</div>

函数看起来像这样:

function typeNumber(num) {
    resultline_str += " " + num;
    document.getElementById('result').innerHTML = resultline_str;
    if (multidigit === 0) {
        operating.push(num);
        multidigit = 1;
    } else {
        if (space === 0) {
            var n = operating[0]
            n = operating[0].toString();
            n += num;
            n = parseInt(n);
            operating[0] = n;
        } else {
            var n = operating[2]
            n = operating[2].toString();
            n += num;
            n = parseInt(n);
            operating[2] = n;
        };
    };
};

但是,您的 divide() 函数不起作用的原因是您将减号而不是除号推入操作数组。您需要将其更改为:

function divide() {
    resultline_str += " /";
    document.getElementById('result').innerHTML = resultline_str;
    operating.push('/');
    multidigit = 0;
    place = 2;
};

开始之前:注意分号。 JavaScript 在分号方面相当宽松,很容易因为放错或遗漏分号而搬起石头砸自己的脚。

正如其他人已经告诉您的那样(我总是迟到,我老了 ;-)):您的代码中有太多重复。例如,您可以创建一个函数来处理输入按钮。在HTML

<td id="1" onclick='getInput(this)'>1</td>

并在脚本中

function getInput(el){
  var value = el.id;
  var num, op;
  num = parseInt(value);
  if(!isNaN(value)){
    // it is a number
    // handle numbers
  } else {
    // it is an operator
    op = value;
    // handle operators
  }
}

或者按照 John Stevens 的建议,将它们分成两个单独的函数,分别用于每个数字和运算符。

但回到您的问题:为什么多位数字不起作用。那么,让我们拆开来看:

function type9() {
  // we got a digit 9 as a string, concatenate it to the resultstring
  resultline_str += " 9";
  // and "print" it
  document.getElementById('result').innerHTML = resultline_str;
  // the first digit doesn't get any special treatment, just
  // shoved on the stack 
  if (multidigit === 0) {
    operating.push(9);
    // flag that we already have one digit on the stack
    multidigit = 1;
  } else {
    // space is alwys 0, it never gets changed anywhere
    // so only the first branch runs, the "else" is never reached
    if (space === 0) {
      // put the value of the zeroth element of "operating" into n
      var n = operating[0];
      // overwrite(!) that with the zeroth element of "operating"
      // cast to a string
      n = operating[0].toString();
      // concatenate the digit 9 as a string to the end of "n"
      n += '9';
      // make an integer Number out of it
      n = parseInt(n);
      // put that number back to the zeroth place in "operators
      operating[0] = n;
    }
    // there is no "else" hence no second operator, everything
    // get shoved into the first one
    else {
      var n = operating[2]
      n = operating[2].toString();
      n += '9';
      n = parseInt(n);
      operating[2] = n;
    }
  }
}

算术运算符

  function type_plus() {
    // print the operator
    resultline_str += " +";
    document.getElementById('result').innerHTML = resultline_str;
    // add the operator to the end of "operating" as a string
    operating.push('+');
    // reset the flag that counts the digits
    multidigit = 0;
    // set "place" to the value 2 as an integer
    place = 2;
  }

实际计算

  function equals() {
    // check for errors: always a good idea!
    if (operating.length != 3) {
      document.getElementById('result').innerHTML = 'Error';
      // reset everything
      multidigit = 0;
      place = 0;
      return;
    } else {
      // iterate over the possible operators
      if (operating[1] === '+') {

        resultline_str = resultline_str + '<br/>' 
              // do the actual addition
              // put it in parenthesis to avoid automatic conversion
              // to a string
              + (parseInt(operating[0]) + parseInt(operating[2])) 
              + '<br/>';
      } else if {
        // let me skip the rest, ok?
      }
    }
    // print the result
    document.getElementById('result').innerHTML = resultline_str;
    // reset all variables
    operating = [];
    multidigit = 0;
    place = 0;
  }

那么,&%$§ 错误在哪里?您已选择 "space" 作为运算符之间不同的变量,但改为使用 "place"。只需将每个 "space" 替换为 "place" 即可。