简体   繁体   中英

function in javascript doesn't work once being trigger?

I am developing a vanilla javascript calculator from scratch. I was able to accomplish the separation between the numbers and operations but once I pass the arrays to another functions that function doesn't work at all for some reason. Please note I'm a self-learner and I'm a beginner javascript developer so I'm in the process to learn and practice. The code:

 //Index.js where the problem is // this the field to control the result textfield var textfield = " "; //this function to copy the number/operations button to the textfiled //it works function retunNumber(val) { console.log(val); if (textfield != " ") { textfield = textfield + val; document.getElementById('result').value = textfield; } else if (textfield == " ") { textfield = val; document.getElementById('result').value = textfield; } } //this function to clear the textfield //it works document.getElementById('clear').addEventListener("click", function(){ document.getElementById('result').value= " "; textfield = " "; }); // This the functions where the calculation spouses to //happen but //nothing //not sure function result(numbers, operations){ var currentResult = numbers[0]; for(var i =0; i<= operations.length ; i++){ if(operations[i] == '+'){ currentResult = currentResult + numbers[i+1]; }else if(operations[i] == '-'){ currentResult = currentResult - numbers[i+1]; }else if(operations[i] == '*'){ currentResult = currentResult * numbers[i+1]; }if(operations[i] == '/'){ currentResult = currentResult / numbers[i+1]; }else{ currentResult = "Wrong"; } }return currentResult; } //this the function where it should give the result // it works partially, only in the separation of the number and the //operation but not in returning the result document.getElementById('equal').addEventListener("click", function(){ var numbers = textfield.split(/\\D/g); var operations = textfield.split(/\\d/g).filter(Boolean); /* console.log(textfield); console.log(numbers); console.log(operations); */ //here is where it spouses to return the result but nothing if(Number.isInteger(result(numbers, operations)) == true){ textfield =result(numbers, operations); }else{ textfield = "Invalid expression" } }); 
 .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 10px; } .container { margin: 10%; } .item1 { grid-column: 1/5; } .item2 { grid-column: 2/4; } .item3 { grid-row: 2; grid-column: 4; } .item4 { grid-row: 3; grid-column: 4; } .item5 { grid-row: 4; grid-column: 4; } .textField { width: 100%; } 
 <html> <head> <title>Calculator</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> </head> <body> <div class="container"> <div class="grid-container"> <div class="item1"> <input type="text" name="result" id="result" class="textField"> </div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="1">1</button> </div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="2">2</button> </div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="3">3</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="4">4</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="5">5</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="6">6</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="7">7</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="8">8</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="9">9</button></div> <div class="item2"> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="0">0</button></div> <div class="item5"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="*">*</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="/">/</button></div> <div class="item3"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="+">+</button></div> <div class="item4"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="-">-</button></div> <div> <button class="btn btn-outline-info" id="equal">Equal</button></div> <div> <button class="btn btn-outline-info">Delete</button></div> <div> <button class="btn btn-outline-info" id="clear">Clear</button></div> </div> </div> </body> <script src="index.js"></script> </html> 

You are assigning a value to textfield but this is just a string, it won't automatically appear in the page.

If you want its value to appear in the page (when pressing 'equals') then you would use:

document.getElementById('result').value = "some value";

Note that you are also calling your function result(numbers, operations) twice, it is better to call it once and store the result.

Another way is to use eval() function.

You can change your event equal like

document.getElementById('equal').addEventListener("click", function(){
    var elResult = document.getElementById('result');
    textfield = " ";
    elResult.value = eval(elResult.value);
})

Or (better) you can use window.Function

document.getElementById('equal').addEventListener("click", function(){
  var elResult = document.getElementById('result');

  textfield = " ";
  elResult.value = Function('"use strict";return (' + elResult.value + ')')();
})

eg

 var newNum = true; function retunNumber(val) { if (newNum) { document.getElementById('result').value = val; newNum = false } else { document.getElementById('result').value += val; } } document.getElementById('clear').addEventListener("click", function() { document.getElementById('result').value = " "; newNum = true; }); document.getElementById('equal').addEventListener("click", function() { var elResult = document.getElementById('result'); newNum = true; elResult.value = Function('"use strict";return (' + elResult.value + ')')(); }) 
 .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 10px; } .container { margin: 10%; } .item1 { grid-column: 1/5; } .item2 { grid-column: 2/4; } .item3 { grid-row: 2; grid-column: 4; } .item4 { grid-row: 3; grid-column: 4; } .item5 { grid-row: 4; grid-column: 4; } .textField { width: 100%; } 
 <html> <head> <title>Calculator</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> </head> <body> <div class="container"> <div class="grid-container"> <div class="item1"> <input type="text" name="result" id="result" class="textField"> </div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="1">1</button> </div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="2">2</button> </div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="3">3</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="4">4</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="5">5</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="6">6</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="7">7</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="8">8</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="9">9</button></div> <div class="item2"> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="0">0</button></div> <div class="item5"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="*">*</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="/">/</button></div> <div class="item3"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="+">+</button></div> <div class="item4"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="-">-</button></div> <div> <button class="btn btn-outline-info" id="equal">Equal</button></div> <div> <button class="btn btn-outline-info">Delete</button></div> <div> <button class="btn btn-outline-info" id="clear">Clear</button></div> </div> </div> </body> <script src="index.js"></script> </html> 

There are a couple small issues.

  1. }if(operations[i] == '/'){ needs to be }else if(operations[i] == '/'){ add the else

  2. for(var i =0; i<= operations.length ; i++){ needs to be for(var i =0; i< operations.length ; i++){ Remove the =

  3. You are assigning to textfield so when you hit equal again, the textfield is no longer the value you think it is. You need to assign textField to the textbox on the page.

  4. Inside of the result function, currentResult and numbers[i+1] are treated as a string type. You need to use parseInt to convert these to an integer.

  5. Number.isInteger will always return false in this situation because the the function result has a return type of string . You need to convert it back to a number by adding + in front of the function call.

  //Index.js where the problem is var textfield = " "; function retunNumber(val) { console.log(val); if (textfield != " ") { textfield = textfield + val; document.getElementById('result').value = textfield; } else if (textfield == " ") { textfield = val; document.getElementById('result').value = textfield; } } document.getElementById('clear').addEventListener("click", function(){ document.getElementById('result').value= " "; textfield = " "; }); // This the functions where the calculation spouses to //happen but nothing function result(numbers, operations){ var currentResult = parseInt(numbers[0]); for(var i =0; i < operations.length ; i++){ if(operations[i] == '+'){ currentResult = currentResult + parseInt(numbers[i+1]); }else if(operations[i] == '-'){ currentResult = currentResult - parseInt(numbers[i+1]); }else if(operations[i] == '*'){ currentResult = currentResult * parseInt(numbers[i+1]); }else if(operations[i] == '/'){ currentResult = currentResult / parseInt(numbers[i+1]); }else{ currentResult = "Wrong"; } }return currentResult; } document.getElementById('equal').addEventListener("click", function(){ var numbers = textfield.split(/\\D/g); var operations = textfield.split(/\\d/g).filter(Boolean); /* console.log(textfield); console.log(numbers); console.log(operations); */ if(Number.isInteger(+result(numbers, operations)) == true){ textfield =result(numbers, operations); }else{ textfield = "Invalid expression" } document.getElementById('result').value = textfield; }); 
 .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 10px; } .container { margin: 10%; } .item1 { grid-column: 1/5; } .item2 { grid-column: 2/4; } .item3 { grid-row: 2; grid-column: 4; } .item4 { grid-row: 3; grid-column: 4; } .item5 { grid-row: 4; grid-column: 4; } .textField { width: 100%; } 
 <html> <head> <title>Calculator</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> </head> <body> <div class="container"> <div class="grid-container"> <div class="item1"> <input type="text" name="result" id="result" class="textField"> </div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="1">1</button> </div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="2">2</button> </div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="3">3</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="4">4</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="5">5</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="6">6</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="7">7</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="8">8</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="9">9</button></div> <div class="item2"> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="0">0</button></div> <div class="item5"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="*">*</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="/">/</button></div> <div class="item3"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="+">+</button></div> <div class="item4"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="-">-</button></div> <div> <button class="btn btn-outline-info" id="equal">Equal</button></div> <div> <button class="btn btn-outline-info">Delete</button></div> <div> <button class="btn btn-outline-info" id="clear">Clear</button></div> </div> </div> </body> <script src="index.js"></script> </html> 

The array of values is a string array, so you must convert every item for number, use parseInt .

/* here must be `else if` */

} if(operations[i] == '/'){ 
        currentResult = currentResult / numbers[i+1];
    }else{
        currentResult = "Wrong";
    } 

OBS: float number will make errors. Precedence ignored.

 //Index.js where the problem is // this the field to control the result textfield var textfield = " "; //this function to copy the number/operations button to the textfiled //it works function retunNumber(val) { if (textfield != " ") { textfield = textfield + val; document.getElementById('result').value = textfield; } else if (textfield == " ") { textfield = val; document.getElementById('result').value = textfield; } } //this function to clear the textfield //it works document.getElementById('clear').addEventListener("click", function(){ document.getElementById('result').value= " "; textfield = " "; }); // This the functions where the calculation spouses to //happen but function result(numbers, operations){ var currentResult = parseInt(numbers[0]); // first of all, convert to number for(var i = 0; i < operations.length ; i++) { // convert to number var currentNumber = parseInt(numbers[i+1]); if(operations[i] == '+') { currentResult += currentNumber } else if(operations[i] == '-') { currentResult -= currentNumber } else if(operations[i] == '*') { currentResult *= currentNumber } else if(operations[i] == '/') { currentResult /= currentNumber } else { currentResult = "Wrong"; } } return currentResult; } //this the function where it should give the result // it works partially, only in the separation of the number and the //operation but not in returning the result document.getElementById('equal').addEventListener("click", function(){ var numbers = textfield.split(/\\D/g); var operations = textfield.split(/\\d/g).filter(Boolean); const res = result(numbers, operations) if( Number.isInteger(res) ) { /* == true <- redundant ){ */ textfield = res; } else { textfield = "Invalid expression" } /* set value to texfield */ document.getElementById('result').value = textfield; }); 
 .grid-container { display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 10px; } .container { margin: 10%; } .item1 { grid-column: 1/5; } .item2 { grid-column: 2/4; } .item3 { grid-row: 2; grid-column: 4; } .item4 { grid-row: 3; grid-column: 4; } .item5 { grid-row: 4; grid-column: 4; } .textField { width: 100%; } 
 <html> <head> <title>Calculator</title> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> </head> <body> <div class="container"> <div class="grid-container"> <div class="item1"> <input type="text" name="result" id="result" class="textField"> </div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="1">1</button> </div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="2">2</button> </div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="3">3</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="4">4</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="5">5</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="6">6</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="7">7</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="8">8</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="9">9</button></div> <div class="item2"> <button onclick="retunNumber(this.value)" class="btn btn-outline-dark" value="0">0</button></div> <div class="item5"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="*">*</button></div> <div> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="/">/</button></div> <div class="item3"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="+">+</button></div> <div class="item4"> <button onclick="retunNumber(this.value)" class="btn btn-outline-info" value="-">-</button></div> <div> <button class="btn btn-outline-info" id="equal">Equal</button></div> <div> <button class="btn btn-outline-info">Delete</button></div> <div> <button class="btn btn-outline-info" id="clear">Clear</button></div> </div> </div> </body> <script src="index.js"></script> </html> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM