Я новичок в javascript, и я не могу заставить его работать.
После нажатия кнопки равенства он запускает функцию calc (), которая должна записывать результат калькулятора на дисплей, но он просто не работает ... Но если я запускаю calc() из консоли разработчика, он работает отлично, поэтому я предполагаю, что что-то не так с какой бы то ни было областью охвата. Может у вас есть идея :)?
Пожалуйста, простите меня за отсутствие обработки ошибок, поскольку я сначала делаю базовые вещи.
/**
* core
*/
var display = null;
var input = null;
var latestNumber = null;
var result = null;
var displayNumber = null;
var operator = null;
function setOperator(operatorValue) {
if (displayNumber === null && operator === null){
displayNumber = readInput();
writeOutput(displayNumber + " " + String(operatorValue));
clearInput();
} else if (displayNumber !== null && operator !== null){
writeOutput( displayNumber + " " + String(operatorValue));
}
operator = String(operatorValue);
}
function addDigit(digit){
let oldValue = readInput();
if (Number.isNaN(oldValue)){
oldValue = "";
}
let newInputValue = String(oldValue) + String(digit); //Parse numbers to string
writeInput(newInputValue);
}
function calc (firstNumber, op, secondNumber){
switch (op) {
case "+":
result = firstNumber + secondNumber;
break;
case "-":
result = firstNumber - secondNumber;
break;
case "*":
result = firstNumber * secondNumber;
break;
case "/":
if (secondNumber === 0) {
window.alert("Error: Division by zero");
}
else {
result = firstNumber / secondNumber;
}
break;
}
operator = null;
latestNumber = null;
displayNumber = null;
writeInput(result);
}
/**
* UI
*/
window.addEventListener('load', function() {
//Initialize number Buttons
(function () {
const numbers = document.getElementsByClassName("number");
for (let i = 0; i < numbers.length; ++i) {
numbers[i].addEventListener('click', () => addDigit(numbers[i].value));
}
})();
//Initialize operation Buttons
(function () {
const operators = document.getElementsByClassName("operator");
for (let i = 0; i < operators.length; ++i) {
operators[i].addEventListener('click', () => setOperator (operators[i].value));
}
})();
//Initialize calc button
(function () {
const equalButton = document.getElementById("key- = ");
equalButton.addEventListener('click', ()=> calc (displayNumber, operator, readInput()));
})();
//Initialize clear button
(function () {
const commands = document.getElementsByClassName("command");
for (let i = 0; i < commands.length; ++i) {
commands[i].addEventListener('click', ()=> clearAll ());
}
})();
//Initialize Display
display = (function (){
return document.getElementById("output");
})();
input = (function () {
return document.getElementById("input");
})();
writeOutput("Welcome");
});
//Function to read from input
function readInput () {
return parseFloat(input.value);
}
//Function to write to input
function writeInput (value) {
input.value = value;
}
//Function to write to output
function writeOutput (string) {
display.value = string;
}
//Function to clear input
function clearInput () {
input.value = "";
}
//Function to clear output
function clearOutput () {
display.value = "";
}
//Function to clear display
function clearAll (){
result = null;
lastNumber = null;
displayNumber = null;
operator = null;
clearInput();
clearOutput();
}/* reset */
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
margin: 0;
padding: 0;
}
html {
font-size: 1vw;
}
html, body {
width: 100%;
margin: 0;
padding: 0;
}
/* document */
body {
font-family: "URW Gothic L", "Helvetica", "Arial", sans-serif;
/* Background source:
* http://www.texturex.com/Leather-Textures/black+leather+texture+large+close+up+grain+material+dark+fabric+stock+photo.jpg.php
* Free offered by Free Leather Textures */
background: url('../../../media/black-leather-texture.jpg');
}
.display {
border: 0.2rem solid gray;
border-radius: 0.5rem;
background: black;
padding: 0.5rem;
width: 100%;
display: block;
}
.display > output {
display: block;
height: 1.5rem;
margin: 0;
color: aqua;
}
form {
width: 100%;
padding: 0.5rem;
}
fieldset {
border: none;
margin: 0;
font-size: 0;
}
fieldset > button {
width: 20%;
margin: 3.3%;
padding: 2vw;
}
fieldset > button:nth-child(4n) {
margin-right: 0;
}
fieldset > button:nth-child(4n+1) {
margin-left: 0;
}
button {
box-shadow: 0 0 0.5rem black;
border: none;
border-radius: 0.5rem;
text-align: center;
vertical-align: middle;
margin: 0;
font-weight: bold;
font-size: 1.5rem;
}
output {
font-size: 1rem;
}
button.number, button.command {
background: white;
}
button.number:active, button.command:active {
background: rgb(230, 230, 230);
box-shadow: inset 0 0 0.5rem black;
}
button.operator {
box-shadow: 0 0 0.5rem rgb(80,80, 80);
background: black;
color: white;
}
button.operator:active {
background: rgb(60, 60, 60);
box-shadow: inset 0 0 0.5rem black;
}
#key-c {
background: red;
color: white;
}
#key-c:active {
background: darkred;
}
button:focus {
box-shadow: 0 0 0.5rem deepskyblue;
}<form>
<fieldset class = "display">
<output name = "output" id = "output" class = "output"></output>
<output name = "input" id = "input" class = "input"></output>
</fieldset>
<fieldset>
<button type = "button" name = "key-0" id = "key-0" class = "number" value = "0">0</button>
<button type = "button" name = "key-1" id = "key-1" class = "number" value = "1">1</button>
<button type = "button" name = "key-2" id = "key-2" class = "number" value = "2">2</button>
<button type = "button" name = "key-+" id = "key-+" value = "+" class = "operator">+</button>
<button type = "button" name = "key-3" id = "key-3" class = "number" value = "3">3</button>
<button type = "button" name = "key-4" id = "key-4" class = "number" value = "4">4</button>
<button type = "button" name = "key-5" id = "key-5" class = "number" value = "5">5</button>
<button type = "button" name = "key--" id = "key--" value = "-" class = "operator">−</button>
<button type = "button" name = "key-6" id = "key-6" class = "number" value = "6">6</button>
<button type = "button" name = "key-7" id = "key-7" class = "number" value = "7">7</button>
<button type = "button" name = "key-8" id = "key-8" class = "number" value = "8">8</button>
<button type = "button" name = "key-*" id = "key-*" value = "*" class = "operator">∗</button>
<button type = "button" name = "key-9" id = "key-9" class = "number" value = "9">9</button>
<button type = "button" name = "key-c" id = "key-c" class = "command">C</button>
<button type = "button" name = "key- = " id = "key- = " class = "command">=</button>
<button type = "button" name = "key-/" id = "key-/" value = "/" class = "operator">÷</button>
</fieldset>
</form>


![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Проблема здесь в том, что кнопки «Очистить» и «Равно» используют один и тот же класс.
Итак, когда вы вызываете функцию equals, она также запускает этот код:
(function () {
const commands = document.getElementsByClassName("command");
for (let i = 0; i < commands.length; ++i) {
commands[i].addEventListener('click', ()=> clearAll ());
}
})();
Вы распечатываете результат, а затем очищаете поле.
Попробуйте изменить класс на кнопке равенства, и это сработает.
<button type = "button" name = "key-c" id = "key-c" class = "command">C</button>
<button type = "button" name = "key- = " id = "key- = " class = "equals">=</button>
Рад помочь. Отметьте вопрос как отвеченный.
Спасибо, вот и все. Изначально у меня был оператор switch для командных кнопок, но я решил добавить слушателей событий отдельно из-за лучшего понимания. Похоже, я забыл удалить старую.