我目前正在做我的计算机学校项目。
如果我单独使用按钮或键盘输入,它工作得很好,但是,在混合输入的情况下会出现问题,特别是当使用Enter
按钮时。
以下是我的完整项目:codepen的数据。
描述问题的最好方法是提供一个简短的示例,仅为1 + 2
。
可能的选项:
1.仅使用按钮,结果正确。
1.只使用按键,结果是正确的。
1.使用混合输入和=
键,结果正确。
1.使用混合输入和Enter
键,出现意外行为。
什么是意外行为?
1.如果第一个数字是通过按钮输入的,而第二个数字是通过键盘输入的,则显示第一个数字而不是结果。
1.如果第二个数字或两个数字都是由按钮引入的,则显示第二个数字而不是结果。
在这两种情况下,随后的Enter
按下只是乘以显示的值,而不是给出错误。
1.这两个数字都是通过键盘输入的,但操作员是通过按钮输入的:程序给出正确的结果,但在冻结之后添加运算符。
下面是我如何处理一个按钮点击:
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;
}
型
我已经做了什么:
1.问题是这个错误不会发生在检查模式下,它在那里正常工作。
1.日志记录提供了预期值,因此没有帮助。
1.在不同的浏览器中,问题是相同的,在调试模式下它消失。
2条答案
按热度按时间woobm2wo1#
我刚刚调试完你的代码。
因此,我认为你的heisenbug是由
enter
键事件引起的。单击按钮时,按钮将获得焦点。然后,如果按enter
键,handleKeyDown()
和handleButtonClick()
都将连续执行。因此,您的display div
首先显示正确的结果,然后重新按下的按钮,导致错误。若要修复此错误,可以使用
blur()
方法从按钮移除焦点。举例来说:
字符串
更新答案
或者,您可以使用
preventDefault()
方法来阻止它触发按钮上的单击事件。举例来说:
型
mbskvtky2#
只需检查handleButtonClick函数中的event.pointerType是否不是Mouse,它就可以工作。谢谢你,谢谢