Task:

There is a simple calculator that adds two numbers. I want to do to not only add, but also to multiply, subtract, divide, even divide by module. When entering in the field

<input type="button" name="symbol" value="">

operator symbol (*, -, +, /,%) performed arithmetic. I suppose there is some kind of closure here.

Please describe in detail, please, why is it advisable to use closure in this example, or vice versa, perhaps there are other options ??

I added a new input lower in the source, compared to the previous link

Source:

 <div class="container"> <input type="text" name="num1" value=""> <input type="button" name="num2" value="="> <input type="button" name="symbol" value=""> <--!добавленный ТЭГ--> <input type="button" name="calc" value="="> <span class="result"></span> </div> 

 let btn = document.querySelector('input[name=calc]'); let num1 = document.querySelector('input[name=num1]'); let num2 = document.querySelector('input[name=num2]'); let result = document.querySelector('.result'); let symbol = document.querySelector('.symbol'); //новое выражение btn.addEventListener('click', totalSum); function totalSum() { } 
  • one
    A closure is the preservation of the context (variables) of the former at the time the function was created. It cannot in any way be related to arithmetic operations. You need in the function that is now adding up, to explicitly get the operation symbol and make a branch (most likely a switch) which, depending on the symbol, will perform this or that operation - Mike
  • So you want to make separate buttons for each operation or one input, where the characters "+", "*", "-" are printed manually and proceeding from them to do the operation? (this is how you can make <select> <option> actually ... with the ability to select the desired option) - OPTIMUS PRIME
  • @OPTIMUS PRIME yes, when I enter the necessary operator so that the arithmetic is done !! In this example, I just want to think over the logic, and not from the point of view of reasonableness, which tag will be more semantic (if there is such a word) - John
  • @Mike and if through this - John
  • @John this is not an operator, but a pointer to the current object. And you don’t have any objects at all. Miracles do not happen unless you explicitly write if(sym=='+') { x=a+b } else if(sym=='-') { x=ab } ... nothing will happen - Mike

2 answers 2

Redid a separate button:

JsFiddle DEMO

There he described in detail all the steps. Although in general, eval () is recommended to be used only in extreme cases ... here I liked this solution, but they should not be scattered everywhere)


The old answer decided not to touch:


With simple operations it is easy, because their entry in JS corresponds to the typed character, and the symbol "%" means "to count the remainder after division".

There is an eval() function that can take any string and execute it as code. Therefore, you can first write the operation as a string using Sting() ...

JsFiddle DEMO

 (function(){ const opera = document.getElementById('opera'); const num1 = document.getElementById('num1'); const num2 = document.getElementById('num2'); const btn = document.getElementById('btn'); const result = document.getElementById('result'); btn.addEventListener('click', function(){ //символ == означает сравнение значений. //Берем значение выбранного символа и сравниваем с "%" if( opera.value == "%" ) { result.innerText = (Number(num1.value)*Number(num2.value))/100 ; } else { //Вот здесь по сути записано (число) + (символ операции) + (число) //Если у нас введено 7 * 5 то записанное равно строке "7*5" result.innerText = eval( String(num1.value + opera.value + num2.value) ); } }); })(); 
 #opera option {font-size:30px;} #opera,#btn,#result {font-size:30px;} input {font-size:30px;width:200px;} 
 <input type="number" id="num1"> <select id="opera"> <option>+</option> <option>-</option> <option>*</option> <option>/</option> <option>%</option> </select> <input type="number" id="num2"> <br><br> <button id="btn">=</button> <span id="result"></span> 

  • I managed! strained my head all day, and not in vain Check it out :) - John

This is what I wanted to achieve [corrected]

 let btn = document.querySelector('input[name=calc]'); let symbol = document.querySelector('input[name=symbol]'); let num1 = document.querySelector('input[name=num1]'); let num2 = document.querySelector('input[name=num2]'); let result = document.querySelector('.result'); btn.addEventListener('click', addition); symbol.addEventListener('input', writeSymbol); num2.addEventListener("input", btnEnable); num1.addEventListener("input", btnEnable); function addition() { let a = parseInt(num1.value); let b= parseInt(num2.value); let res; if (symbol.value === "+"){ res = a + b; } else if(symbol.value === "*"){ res = a * b; } else if(symbol.value === "-"){ res = a - b; } else{ alert('incorrect symbol') } result.textContent = res; btn.disabled = true; } function writeSymbol(){ this.setAttribute("value", this.value); btn.disabled = false; } function btnEnable(){ btn.disabled = false; } 
 <input type="text" name="num1" value=""> <input type="text" name="symbol"> <input type="text" name="num2" value=""> <input type="button" name="calc" value="="> <span class="result"></span> 

  • The first if by the way is superfluous) let res and so equal to their sum. If, when loading, the choice will initially be in the amount, then it will count res. And if to change the res, you can already start with '*' [here you can == instead of ===] // by the way, onclick, oninput and the like - can take on single values. For one button there can not be several onclick (as there can not be several separate style = "..." style = "...") - the last one will be in priority. Here, in principle, does not interfere, but if the code is very large, sometimes you need to hang a few clicks on one button ... because it is recommended to write via addEventListener) - OPTIMUS PRIME
  • @ OPTIMUS PRIME thanks for the comment! The fact is that I could not find an alternative to the oninput event for addEventListener, can you tell me! - John
  • There is almost the same thing everywhere, just remove on → ... addEventListener ('click', function () {...}); instead of 'click', there may be → input (starts the function when entering text), change (when the focus changes from the element), mouseover (when the cursor is hovering), keyup (the same input, only works when any button is pressed), mouseenter (like only the mouse enters the area inside the element), mouseleave (leaves) ... from what he remembered. - OPTIMUS PRIME