向JS计算器添加键盘支持时出现问题 [英] Problems with adding keyboard support to JS calculator

查看:48
本文介绍了向JS计算器添加键盘支持时出现问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为计算器添加键盘支持。当我用键盘按操作时(即+,-,*或/),js将其视为数字而不是操作。

I want to add keyboard support to my calculator. When i press operations with keyboard (i.e. +,-,* or /) js sees it as number, not as operation.

例如,当我通过单击计算 10 + 11时,结果将是 21。当我通过键盘输入同样的内容时,我会得到 10。

For example, when I compute "10+11" by clicking, I will get "21" as a result. When I do the same with inputing through keyboard, I will get "10".

为什么会发生?可以更改它吗?

Why does it happen? And is it possible to change it?

<!DOCTYPE html>
<html>
    <head>
        <link href="style.css" type="text/css" rel="stylesheet">
    </head>
    <body>
        <div class="main">
            <div id="output">
                <input id="display" value="0">
            </div>
            <button class="clear" id="ce">CE</button>
            <button class="clear" id="c">C</button>
            <button class="operation" id="slash">/</button>
            <button class="number" id="seven">7</button>
            <button class="number" id="eight">8</button>
            <button class="number" id="nine">9</button>
            <button class="operation" id="star">*</button>
            <button class="number" id="four">4</button>
            <button class="number" id="five">5</button>
            <button class="number" id="six">6</button>
            <button class="operation" id="minus">-</button>
            <button class="number" id="one">1</button>
            <button class="number" id="two">2</button>
            <button class="number" id="three">3</button>
            <button class="operation" id="plus">+</button>
            <button class="number" id="zero">0</button>
            <button class="decimal" id="dot">.</button>
            <button class="operation" id="equal">=</button>
                </div>
        
        <script>
let numberBtn=document.querySelectorAll(".number"),
    operationBtn=document.querySelectorAll(".operation"),
    clearBtn=document.querySelectorAll(".clear"),
    decimalBtn=document.querySelector(".decimal"),
    currentValue=0,
    isNewValue= false,
    currentOperation=null,
    phrase="ошибка";
    display=document.getElementById('display');

    for (let i=0; i<operationBtn.length; i++) {
        operations=operationBtn[i];
        operations.addEventListener ('click', function (e) {
            operate (e.target.textContent);
        });
    }

    for (let i=0; i<operationBtn.length; i++) {
        op=operationBtn[i];
        op.addEventListener ('keypress', function (e) {
            operate (e.key);
        });
    }
    for (let i=0; i<numberBtn.length; i++) {
    numbers=numberBtn[i];
    
    numbers.addEventListener ('click', function (e) {
        numberPress (e.target.textContent);
        
    });
}

for (let i=0; i<numberBtn.length; i++) {
    numbers=numberBtn[i];
    numbers.addEventListener ('keypress', function (e) {
        numberPress (e.key)
    });
}



for (let i=0; i<clearBtn.length; i++) {
    clears=clearBtn[i];
    clears.addEventListener ('click', function (e) {
        console.log (e.srcElement.id);
        clear(e.srcElement.id);
    });
}

function numberPress(numbers) {
    if (isNewValue) {
        display.value=numbers;
        isNewValue=false;
        console.log ('1');
    } else {
        if (display.value==0 && display.value!=='0.') {
        display.value=numbers;
        console.log ('2');
        } else {
            display.value+=numbers;
            console.log ('3');
        }
    }
    }


function operate(op) {
    localOperationMemory=display.value;
    if (isNewValue && currentOperation!=="=") {
        currentValue=display.value;
        console.log ('4');
    } else {
        isNewValue=true;
        if (currentOperation=="+") {
            currentValue+=parseFloat (localOperationMemory);
            console.log ('5');
        } else if (currentOperation=="-") {
            currentValue-=parseFloat(localOperationMemory);
            console.log ('6');
        } else if (currentOperation=="*") {
            currentValue*=parseFloat (localOperationMemory);
            console.log ('7');
        } else if (currentOperation=="/") {
            currentValue/=parseFloat (localOperationMemory);
            console.log ('8');
        } else {
            currentValue=parseFloat (localOperationMemory);
            console.log ('9');
        }
        display.value=(Math.round(currentValue*100)/100);
        currentOperation=op;
        divideZero ()
    }
}

        </script>
    </body>
</html>

推荐答案

试一下。它没有用于删除键或箭头键的任何功能,但可能会帮助您进一步前进。

Give this a shot. It's not got any functionality for delete key or arrow keys, but it will perhaps help move you forward more.

<!DOCTYPE html>
<html>
    <head>
    </head>
    <script>
      var values
      var dp
      function checkCalcKey(key) {
        switch (key) {
          case '.':
            document.getElementById('dot').click();
            break;
          case '0':
          case '1':
          case '2':
          case '3':
          case '4':
          case '5':
          case '6':
          case '7':
          case '8':
          case '9':
          case '+':
          case '-':
          case '/':
          case '*':
          case '=':
            document.getElementById(key).click();
            break;
        }
        return false;
      // TODO handle any of 'ArrowLeft', 'ArrowRight', 'Delete','Backspace'. I'll leave this as an exercise for you to complete!
      }
      function hardReset() {
          values = [];
          opcode = null;
          clear = true;
          reset();
      }
        
      function reset() {
        newNumber = false;
        if (opcode === null) {
           clearDisplay()
        }    
      }
        
      function clearDisplay() {
          dp = 0;
          nc = 0;
          document.getElementById('display').value = '';
      }
        
      function getValue() {
          var value;
          var s = '' + document.getElementById('display').value;
          if (s === '') {
              value = 0;
          } else if (s.indexOf('.') === -1) {
            value = Number(s);
          } else {
            value = parseFloat(s);
          }
          return value;
      }
        
      function performMaths() {
            m = values.pop();
            v = values.pop();
            switch (opcode) {
              case '+':
                v += m;
                break;
              case '-':
                v -= m;
                break;
              case '*':
                v *= m;
                break;
              case '/':
                if ( m=== 0) {
                   v = NaN;
                } else {
                   v /= m;
                }
                break;
            }
            values = [v,m];
            document.getElementById('display').value = v;
      }
        
      function init() {
        clear = true;
        hardReset();
        document.querySelectorAll(".number").forEach((b) => {
           b.addEventListener('click', (e) => 
              {
                newNumber = true;
                if (clear) {
                    clearDisplay();
                    clear = false;
                }
                nc++;
                display=document.getElementById('display');
                if (dp === 0) {
                   var value = (10 * Number(display.value)) + Number(e.target.textContent);
                   display.value = value;
                } else {
                   var f = Number(e.target.textContent) / Math.pow(10,dp);
                   var value = parseFloat(display.value);
                   var value = f + value;
                   var sv = '' + value
                   sv = sv.substring(0,nc);
                   display.value = sv;
                   dp++;
                }
              });
         });
          
         document.getElementById('dot').addEventListener('click', () => {
            newNumber = true;
            if (dp === 0) {
                dp++;
                nc++;
            }
         });
          
         document.getElementById('c').addEventListener('click', () => {
            hardReset();
         });
          
         document.getElementById('ce').addEventListener('click', () => {
            reset();
         });
          
         document.querySelectorAll(".operator").forEach((b) => {
           b.addEventListener('click', (e) => 
              {
                clear = true;
                if (e.target.textContent != opcode) {
                  opcode = e.target.textContent;
                }
                if (document.getElementById('display').value != '') {
                  if (values.length === 2) {
                      values.shift();
                  }
                 values.unshift(getValue());
                }
               newNumber = false;
              });
         });
          
         document.getElementById('=').addEventListener('click', () => {
           if (values.length === 2) {
              if (newNumber) {
                values.pop();
                values.push(getValue());
              }
           } else {
             values.push(getValue());
           }
           performMaths();
           newNumber = false;
         });
      }
        
    </script>
    <body onload="init()">
        <div class="main">
            <div id="output">
                <input id="display" value="" onkeydown="return checkCalcKey(event.key)">
            </div>
            <button id="ce">CE</button>
            <button id="c">C</button>
            <button id="0" class="number">0</button>
            <button id="1" class="number">1</button>
            <button id="2" class="number">2</button>
            <button id="3" class="number">3</button>
            <button id="4" class="number">4</button>
            <button id="5" class="number">5</button>
            <button id="6" class="number">6</button>
            <button id="7" class="number">7</button>
            <button id="8" class="number">8</button>
            <button id="9" class="number">9</button>
            <button id="/" class="operator">/</button>
            <button id="*" class="operator">*</button>
            <button id="-" class="operator">-</button>
            <button id="+" class="operator">+</button>
            <button id="=">=</button>
            <button id="dot">.</button>
        </div>
    </body>
</html>

代码的解释:

getValue 例程会做大量的工作,并回答您的关键点原始问题:

The getValue routine does the bulk of fixing things up, and answers the key points in your original question:


  • 如果将变量解释为字符串类型,则可能会使计算混乱。
    因此,您可以通过
    将空字符串与变量本身结合起来,将不知道类型的变量转换为字符串。

  • If a variable is being interpreted as of type string it can mess up the computation. So you can convert a variable you don't know the type of to string by combining an empty string with the variable itself.

有代码检查小数点是否存在,然后使用 parseFloat Number 投射变量的类型( parseInt 是更冗长的替代方案,需要以10为基数-以10为基数的数字。)

There is code to check for the existence of a decimal point, then use either parseFloat or Number to cast the type of the variable (parseInt is a more verbose alternative, needing radix of 10 - for a base 10 number).

其他几个关键变量是:


  • dp (小数点)。它代表小数点后的位数,因此您添加的任何数字都将除以10 ^ dp(因此dp后的1位为 n * 1 / 10,2位为 n * 1/100等)。

  • nc (字符数)。有时您会遇到奇怪的舍入错误,因此诸如1.111之类的东西突然变成1.111000000001之类的东西,因此 nc 用于计算输入的数字和小数位数,并根据 nc

  • dp (decimal point). It stands for the number of digits past the decimal point, so any numbers you add after are divided by 10^dp (so 1 digit after dp is n * 1/10th, 2 digits is n * 1/100th etc).
  • nc (number of characters). Sometimes you can get odd rounding errors, so things like 1.111 suddenly become 1.111000000001 or something like that, so nc is used to count digits and decimal places entered and take the left number of characters based on nc.

还有一些时髦的东西,模仿普通的计算器。
因此,当计算继续时,您可以执行以下输入操作:

There is also some funky stuff going on, mimicking a normal calculator. So that when computation goes on, you can do something like enter:


  • 5 * =给出25。 li>
  • 再次按=,它会给您125。

所以最后一个数字将变成内存中的粘性常量。每当输入新值时,该值即成为新的粘性值。因此:

So the last number you enter becomes like a 'sticky' constant in memory. Whenever a new value gets entered, that becomes the new 'sticky' value. So:


  • 3 * 4 =(收益率12),

  • =然后收益率48等等。

因此:
- values 数组用于存储粘性值和总计:

So: - the values array is used to store both the sticky value and the total:


  • 它会在 performMaths()
  • 中重新评估>在 operator = 事件处理程序中进行了调整。


    • 每按一个数字,布尔值 newValue 就会设置为 true ,而 false 每次操作,例如 + - / * =

    • It gets re-evaluated in performMaths()
    • adjusted in operator and = event handlers.
      • the boolean newValue is set to true whenever a number is pressed, and false whenever an operation, such as +, -, /, * or = is pressed.

      checkCalcKey()是用于 input HTML控件上的 onkeydown 。通过返回 false ,它可以防止您键入的字符来自构建输入。相反,它遵循相应按钮的单击处理程序,并且通过该处理程序执行输入控件 value 属性中的任何字符输入。 (更多信息此处)。

      checkCalcKey() is an event handler for onkeydown upon the input HTML control's. By returning false, it prevents the character you type from build input. Instead it defers to the click handler of the corresponding button and any character entry into the input control value property gets performed via that handler instead. (More info here).

      这篇关于向JS计算器添加键盘支持时出现问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆