2017-12-31 117 views
-1

Ich habe einen Rechner mit JavaScript erstellt. Wenn ich mehrere mathematische Probleme zusammenfüge, bekomme ich die Antwort, die ich begehre, bis ich versuche, das Endergebnis mit der Taste = zu erhalten. Wenn ich nur zwei Zahlen mache, funktioniert der = Button einwandfrei. Ich habe meinen Code eingerichtet, um die a MathHoldOne und MathHoldTwo einzustellen. Beide enthalten eine Zahl und einen Booleschen Wert, wenn der Wert gesetzt ist oder nicht. Ich habe Dev-Tools überprüft, um zu sehen, was der Unterschied zwischen einem Problem mit zwei Zahlen und einem Problem mit 2+ Zahlen ist, und ich kann nicht scheinen, das Problem zu finden. codepenJavascript Rechner gleiche Funktion fehlgeschlagen

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 = ''; 
    } 
} 
+1

denken jemals mit 'eval' oder' neue Function' für Grundrechenprobleme? Ich denke, Sie haben auch ein Problem mit der Multiplikationsfunktion (scheint in der 'case ('cell equal') Anweisung ifs Block geschrieben zu sein). Ich glaube auch, dass dein Code übermäßig komplex ist (zum Beispiel, in jedem Case-Block nennst du das 'if (mathHoldOne.set && mathHoldTwo.set)'), aber du bewertest es etwas dynamisch. Im übrigen scheinst du das zu vergessen ' 5 + 3 * 5 'ist' 20 ', während ich denke, dass Ihr Code es als' 40 'bewerten würde, wenn Sie die Anweisungen auf einmal ausführen – Icepickle

Antwort

0

Obwohl es nicht eine einzige Antwort auf Ihre Frage geben könnte, ich dachte, dass ich eine andere Version von Ihrem Rechner bieten konnte.

Die Hauptsache hier ist, dass die Berechnung durch die new Function-Anweisung aufgehoben wird, die es Ihnen ermöglicht, eine Zeichenfolge als (ein isoliertes Stück) JavaScript-Code auszuführen.

Die Berechnung wird aufgebaut, wenn Sie auf die Schaltflächen klicken. Da das Ausgeben falscher Anweisungen nicht ausgeschlossen ist, wird der Code in einen try/catch-Block gesetzt. Im catch-Block können Sie den Benutzer anzeigen, dass die Berechnung er war ungültig eingegeben, in der aktuellen Version es nur den Fehler protokolliert und gibt 0.

function executeCalculation(calculation) { 
    var fn = new Function(`return (${calculation});`); 
    try { 
    return fn(); 
    } catch (ex) { 
    console.log(ex); 
    return 0; 
    } 
} 

Die Tatsache, dass die vollständige Berechnung auf einmal ausgewertet wird eine Vorteil, da dann die order of operators wie erwartet erhalten bleibt. Ein Beispiel für diese Reihenfolge wäre die, die ich in den Kommentaren hinterlassen habe. Der Versuch, 5 + 3 * 5 zu berechnen, sollte 20 ergeben, aber in Ihrer aktuellen Berechnung wird 5 + 3 = 8 * 5 = 40 ausgewertet.

// 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>

Verwandte Themen