我使用JavaScript创建了一个计算器。当我将多个数学问题链接在一起时,我得到了我想要的答案,直到我尝试用=按钮获得最终结果。当我只做两个数字时,=按钮完全正常。我设置了我的代码来设置mathHoldOne和mathHoldTwo。两者都包含一个数字和一个布尔值,如果它的设置与否。我已经检查了开发工具,看看两个数字的问题和2+数字的问题之间有什么区别,我似乎无法找到问题。 codepen
const view = {
//Updates view when buttons are clicked
updateView: function () {
let viewScreen = document.getElementsByClassName('js-view')[0];
let miniView = document.getElementsByClassName('mini-view')[0];
viewScreen.innerHTML = '';
miniView.innerHTML = '';
const jsContainer = document.getElementsByClassName('js-container')[0];
jsContainer.addEventListener('click', function (e) {
let show = e.target.innerHTML;
viewScreen.innerHTML += show;
});
},
//have a handler that sets what each button does with event delegation
btnHandle: function () {
let mathType = {"type": undefined};
let mathHoldOne = {"num": 0, "set": false};
let mathHoldTwo = {"num": 0, "set": false};
let btnHandler = document.querySelector('.js-container');
btnHandler.addEventListener('click', function (event) {
let btn = event.target;
let screenValue = document.querySelector('.js-view');
let miniView = document.querySelector('.mini-view');
switch (btn.className) {
//clears whats in the view window
case('cell clear'):
screenValue.innerHTML = '';
miniView.innerHTML = '';
mathHoldOne.num = 0;
mathHoldOne.set = false;
mathHoldTwo.num = 0;
mathHoldTwo.set = false;
mathType.type = undefined;
break;
case('cell math multiply'):
//assigns mathHoldTwo.num if mathHoldOne.set is true and blanks the screenValue
if (mathHoldOne.set) {
mathHoldTwo.num = parseInt(screenValue.innerHTML);
mathHoldTwo.set = true;
screenValue.innerHTML = '';
//if mathHoldOne.set is false it assigns mathHoldOne.num and sets the set property to true
//also sets mathType.type to multiply
} else {
mathHoldOne.num = parseInt(screenValue.innerHTML);
mathHoldOne.set = true;
screenValue.innerHTML = '';
mathType.type = "mulitply";
}
if (mathHoldOne.set && mathHoldTwo.set) {
//if both numbers are set cycle through calcFunc to find which mathType.type matches
//and execute that function with the two values
for (let name in calcFunc) {
if (mathType.type === name) {
miniView.innerHTML = calcFunc[name](mathHoldOne.num, mathHoldTwo.num);
mathHoldOne.num = calcFunc[name](mathHoldOne.num, mathHoldTwo.num);
}
}
mathHoldTwo.num = 0;
mathHoldTwo.set = false;
mathType.type = 'multiply';
}
break;
case('cell math divide'):
if (mathHoldOne.set) {
mathHoldTwo.num = parseInt(screenValue.innerHTML);
mathHoldTwo.set = true;
screenValue.innerHTML = '';
} else {
mathHoldOne.num = parseInt(screenValue.innerHTML);
mathHoldOne.set = true;
screenValue.innerHTML = '';
mathType.type = "divide";
}
if (mathHoldOne.set && mathHoldTwo.set) {
for (let name in calcFunc) {
if (mathType.type === name) {
miniView.innerHTML = calcFunc[name](mathHoldOne.num, mathHoldTwo.num);
mathHoldOne.num = calcFunc[name](mathHoldOne.num, mathHoldTwo.num);
}
}
mathHoldTwo.num = 0;
mathHoldTwo.set = false;
mathType.type = 'divide';
}
break;
case('cell math add'):
if (mathHoldOne.set) {
mathHoldTwo.num = parseInt(screenValue.innerHTML);
mathHoldTwo.set = true;
screenValue.innerHTML = '';
} else {
mathHoldOne.num = parseInt(screenValue.innerHTML);
mathHoldOne.set = true;
screenValue.innerHTML = '';
mathType.type = "add";
}
if (mathHoldOne.set && mathHoldTwo.set) {
for (let name in calcFunc) {
if (mathType.type === name) {
miniView.innerHTML = calcFunc[name](mathHoldOne.num, mathHoldTwo.num);
mathHoldOne.num = calcFunc[name](mathHoldOne.num, mathHoldTwo.num);
}
}
;
mathHoldTwo.num = 0;
mathHoldTwo.set = false;
mathType.type = 'add';
}
break;
case('cell math subtract'):
if (mathHoldOne.set) {
mathHoldTwo.num = parseInt(screenValue.innerHTML);
mathHoldTwo.set = true;
screenValue.innerHTML = '';
} else {
mathHoldOne.num = parseInt(screenValue.innerHTML);
mathHoldOne.set = true;
screenValue.innerHTML = '';
mathType.type = "subract";
}
if (mathHoldOne.set && mathHoldTwo.set) {
for (let name in calcFunc) {
if (mathType.type === name) {
miniView.innerHTML = calcFunc[name](mathHoldOne.num, mathHoldTwo.num);
mathHoldOne.num = calcFunc[name](mathHoldOne.num, mathHoldTwo.num);
}
}
;
mathHoldTwo.num = 0;
mathHoldTwo.set = false;
mathType.type = 'subtract';
}
break;
case('cell equal'):
mathHoldTwo.num = parseInt(screenValue.innerHTML);
if (mathType.type === "add") {
screenValue.innerHTML = calcFunc.add(mathHoldOne.num, mathHoldTwo.num);
miniView.innerHTML = calcFunc.add(mathHoldOne.num, mathHoldTwo.num);
mathHoldTwo.num = 0;
mathHoldOne.num = 0;
mathHoldOne.set = false;
} else if (mathType.type === "subract") {
screenValue.innerHTML = calcFunc.subtract(mathHoldOne.num, mathHoldTwo.num);
miniView.innerHTML = calcFunc.subtract(mathHoldOne.num, mathHoldTwo.num);
mathHoldOne.num = (mathHoldOne.num - mathHoldTwo.num);
mathHoldTwo.num = 0;
mathHoldOne.num = 0;
mathHoldOne.set = false;
}
else if (mathType.type === "mulitply") {
screenValue.innerHTML = calcFunc.multiply(mathHoldOne.num, mathHoldTwo.num);
miniView.innerHTML = calcFunc.multiply(mathHoldOne.num, mathHoldTwo.num);
mathHoldOne.num = (mathHoldOne.num * mathHoldTwo.num);
mathHoldTwo.num = 0;
mathHoldOne.num = 0;
mathHoldOne.set = false;
} else if (mathType.type === "divide") {
screenValue.innerHTML = calcFunc.divide(mathHoldOne.num, mathHoldTwo.num);
miniView.innerHTML = calcFunc.divide(mathHoldOne.num, mathHoldTwo.num);
mathHoldOne.num = (mathHoldOne.num / mathHoldTwo.num);
mathHoldTwo.num = 0;
mathHoldOne.num = 0;
mathHoldOne.set = false;
}
break;
}
console.log(mathHoldOne, mathHoldTwo, mathType.type);
})
}
};
view.updateView();
view.btnHandle();
const calcFunc = {
add: function (x, y) {
return x + y;
},
subtract: function (x, y) {
return x - y;
},
multiply: function (x, y) {
return x * y;
},
divide: function (x, y) {
return x / y;
},
clear: function () {
let view = document.querySelector('js-view');
view.innerHTML = '';
}
}
答案 0 :(得分:0)
虽然它可能无法为您的问题提供单一答案,但我认为我可以提供不同版本的计算器。
这里的主要内容是通过new Function
语句解除计算,该语句允许您将字符串作为(一段孤立的)JavaScript代码执行。
单击按钮时会计算出计算结果。因为它不排除给出错误的语句,所以代码放在try / catch块中。在catch块中,您可以向用户指示他输入的计算无效,在当前版本中它只记录错误并返回0.
function executeCalculation( calculation ) {
var fn = new Function( `return (${calculation});` );
try {
return fn();
} catch (ex) {
console.log( ex );
return 0;
}
}
同时评估完整计算的事实是一个优势,因为order of operators按预期保留。此订单的一个示例是我在评论中留下的一个示例,尝试计算5 + 3 * 5
应该导致20
,但在您当前的计算中,它将评估为5 + 3 = 8 * 5 = 40
。
// attach basic event handlers
document
.querySelectorAll('button')
.forEach(
button => button.addEventListener('click', updateCalculation )
);
// some global variables
let currentCalculation = '';
let currentValue = 0;
let memory = 0;
// event handler for clicking on the buttons
function updateCalculation( e ) {
let source = e.target;
if (!source) {
return;
}
// use the data-type attribute to check what action needs to be performed
let type = source.getAttribute('data-type');
if (!type) {
return;
}
switch (type) {
case '=':
currentValue = executeCalculation( currentCalculation );
currentCalculation = '';
break;
case 'clear-view':
currentCalculation = '';
break;
case 'clear-all':
currentValue = 0;
currentCalculation = '';
break;
case 'store':
memory = currentValue;
break;
case 'retrieve':
currentCalculation += memory;
break;
case 'clear':
memory = 0;
break;
case '*':
case '+':
case '-':
case '/':
// in case the currentCalculation is empty, it should start with the current value instead
if (currentCalculation === '') {
currentCalculation = currentValue;
}
currentCalculation += type;
break;
default:
currentCalculation += type;
}
// update the screen with the changes
updateView( currentValue, currentCalculation );
}
function updateView( value, calculation ) {
document.querySelector('.entry').innerHTML = value;
document.querySelector('.current-query').innerHTML = calculation;
}
// executes and returns the result of the calculation
function executeCalculation( calculation ) {
var fn = new Function( `return (${calculation});` );
try {
return fn();
} catch (ex) {
console.log( ex );
return 0;
}
}
.calculator {
background-color: #000;
display: inline-block;
}
button {
margin: 3px;
}
.entry {
display: block;
margin: 3px;
padding: 5px;
color: #fff;
text-align: right;
border: inset #fff 1px;
}
.current-query {
font-size: 0.7em;
text-align: right;
color: #fff;
height: 20px;
}
.row {
display: flex;
flex-flow: row nowrap;
}
.column {
display: flex;
flex-flow: column nowrap;
}
<div class="calculator">
<div class="header">
<div class="view">
<div class="entry">0</div>
<div class="current-query"></div>
</div>
</div>
<div class="quick-buttons">
<button type="button" data-type="clear-view">CE</button>
<button type="button" data-type="clear-all">C</button>
<button type="button" data-type="store">M</button>
<button type="button" data-type="retrieve">MR</button>
<button type="button" data-type="clear">MC</button>
</div>
<div class="main-buttons row">
<div class="numbers column">
<div class="row">
<button type="button" data-type="7">7</button>
<button type="button" data-type="8">8</button>
<button type="button" data-type="9">9</button>
</div>
<div class="row">
<button type="button" data-type="4">4</button>
<button type="button" data-type="5">5</button>
<button type="button" data-type="6">6</button>
</div>
<div class="row">
<button type="button" data-type="1">1</button>
<button type="button" data-type="2">2</button>
<button type="button" data-type="3">3</button>
</div>
<div class="row">
<button type="button" data-type="0">0</button>
<button type="button" data-type=".">.</button>
<button type="button" data-type="=">=</button>
</div>
</div>
<div class="operations row">
<div class="column">
<button type="button" data-type="+">+</button>
<button type="button" data-type="-">-</button>
<button type="button" data-type="*">*</button>
<button type="button" data-type="/">/</button>
</div>
</div>
</div>
</div>