JavaScript计算器混合输入(Enter键)引发Heisenbug问题求助
计算器混合输入(Enter键触发)异常问题
我正在开发一个学校计算器项目,单独使用按钮或键盘输入时功能正常,但混合输入(尤其是按下Enter键)时出现异常。
以计算1 + 2为例:
- 仅用按钮输入:结果正确
- 仅用键盘输入:结果正确
- 混合输入并按
=键:结果正确 - 混合输入并按Enter键:出现异常
异常表现
- 第一个数用按钮输入,第二个数用键盘输入:显示第一个数而非结果
- 第二个数或两个数用按钮输入:显示第二个数而非结果;后续按Enter键会将显示值相乘而非报错
- 两个数用键盘输入,运算符用按钮输入:结果正确但会追加运算符并冻结
相关处理函数
按钮点击处理函数
function handleButtonClick(event) { const buttonClicked = event.target; hideErrorIfEqualErrorDisplayed('mouse', buttonClicked); switch (buttonClicked) { case buttonDecimalPoint: handleDecimalPointButton(); break; case buttonClear: clearAll(); break; case buttonDelete: deleteLastSymbol(); break; case buttonEqual: handleEqualSign(); break; default: const classButton = buttonClicked.classList; const valueOfClickedButton = buttonClicked.textContent; if (classButton.contains('button-digit')) { handleDigitButton(valueOfClickedButton); } else if (classButton.contains('button-operator')) { handleOperatorButton(valueOfClickedButton); } break; } }
键盘输入处理函数
function handleKeyDown(event) { const keyPressed = event.key; hideErrorIfEqualErrorDisplayed('keyboard', keyPressed); switch (keyPressed) { case SYMBOLS.DOT: if (isDecimalPointDisabled) { event.preventDefault(); } else { handleDecimalPointButton(); } break; case SYMBOLS.BACKSPACE: deleteLastSymbol(); break; case SYMBOLS.ESCAPE: clearAll(); break; case SYMBOLS.EQUAL: case SYMBOLS.ENTER: console.log(keyPressed); if (isZeroError) { event.preventDefault(); } else { console.log(`current display: ${containerDisplay.textContent}`); console.log('Go to handleEqualSign()'); handleEqualSign(); } console.log('break'); break; default: if (checkIfDigit(keyPressed)) { handleDigitButton(keyPressed); } else if (Object.values(OPERATORS).includes(keyPressed)) { if (areOperatorsDisabled) { event.preventDefault(); } else { handleOperatorButton(keyPressed); } } else { event.preventDefault(); } break; } }
其他相关函数
function handleEqualSign(){ if (!isSecondNumber) { showErrorMessage(errorEqual); return; } console.log('Go to getResult()'); getResult(); } function hideErrorIfEqualErrorDisplayed(inputSource, symbolTyped) { // inputSource: keyboard or mouse if (isEqualError) { if (inputSource === 'mouse' && symbolTyped !== buttonEqual) { hideErrorMessage(errorEqual); } else if (inputSource === 'keyboard' && symbolTyped !== SYMBOLS.ENTER && symbolTyped !== SYMBOLS.EQUAL) { hideErrorMessage(errorEqual); } } } function handleOperatorButton(operatorValue) { disableButton(buttonDecimalPoint); if (isOperator) { // Display and use the last operator if the user has clicked more than one in a row deleteLastSymbol(); } if (!isSecondNumber) { shiftFromFirstToOperator(); } else { getResult(isAfterEqualClick=false); } addToDisplay(operatorValue, gap=true) operator = operatorValue; } function getResult(isAfterEqualClick=true) { // isAfterEqualClick = true when we enter the function after the clicking '=' or pressing the 'Enter' key, false after clicking any other operator. const result = operate(parseFloat(number1), parseFloat(number2), operator); console.log(`getResult() arguments: ${parseFloat(number1)}, ${parseFloat(number2)}, ${operator} `); console.log(`Result: ${result}`); containerDisplay.textContent = parseFloat(result.toFixed(5)); console.log(`containerDisplay.textContent: ${containerDisplay.textContent }`); number1 = result.toString(); isResult = true; number2 = EMPTY; isSecondNumber = false; if (isAfterEqualClick) { console.log('isAfterEqualClick = True'); isFirstNumber = true; isOperator = false; operator = EMPTY; } else { console.log('isAfterEqualClick = False'); shiftFromFirstToOperator(); } if (!Number.isInteger(result)) { disableButton(buttonDecimalPoint); } else { enableDecimalPointIfDisabled(); } } function handleDigitButton(digitValue) { if (isFirstNumber) { handleFirstNumber(digitValue); } else if (isOperator && !isSecondNumber) { handleStartOfSecondNumber(digitValue); } else { handleContinueOfSecondNumber(digitValue); } } function add(addend1, addend2) { return addend1 + addend2; }
已排查情况
- 该Bug在检查模式下不出现,功能正常
- 日志输出符合预期,无法定位问题
- 不同浏览器均存在该问题,调试模式下问题消失
内容的提问来源于stack exchange,提问作者Lisbeth
相关产品推荐
相关产品推荐

