Я знаю, что похожие вопросы задали ранее. Но всё-таки мне хотелось бы узнать, можно ли написать функцию для калькулятора, опираясь на код, мной написанный до сих пор.
Знаю, как сделать простейший калькулятор для сложения эксклюзивно:
<input id="num1"/>
<p>+</p>
<input id="num2"/>
<button onclick="func()">равняется...</button>
<p id="result"></p>
<script>
function func(){
var num1 = Number(document.getElementById("num1").value);
var num2 = Number(document.getElementById("num2").value);
var result = num1 + num2;
document.getElementById("result").innerHTML = result;
}
</script>
До сих пор, нет сомнений. Но сейчас, мне хотелось бы заменить статичный знак плюса (+) четырьмя кнопками для всех базовых операций: сложения (+), вычитания (-), умножения (x), деления (:).
Интерфейс и распределения кнопок умею вставить, но не успеваю создать функцию, которая изменяет оператор в переменной result в зависимости от избранной кнопки операции.
Нужно ли делать отдельную функцию для каждой кнопки операторов? Или можно вставить всю программу в функцию кнопки выполнения ("равняется...")?
Вот код, написанный до сих пор:
<input id="num1"/>
<div id="operator_btns">
<button id="plus" class="operator">+</button>
<button id="minus" class="operator">-</button>
<button id="times" class="operator">x</button>
<button id="divide" class="operator">:</button>
</div>
<input id="num2"/>
<button onclick="func()">равняется...</button>
<p id="result"></p>
<script>
function func(){
var num1 = Number(document.getElementById("num1").value);
var num2 = Number(document.getElementById("num2").value);
result = ???
document.getElementById("result").innerHTML = result;
}
</script>
Какой будет функция переменной result? Спасибо за помощь!
Вариантов много. Например, при нажатии на кнопку оператора, соответствующе устанавливаем переменную текущего оператора. Затем, при нажатии на кнопку равняется
считаем результат в зависимости от текущего оператора.
<input id="num1" />
<div id="operator_btns">
<button id="plus" class="operator" onclick="op='+'">+</button>
<button id="minus" class="operator" onclick="op='-'">-</button>
<button id="times" class="operator" onclick="op='*'">x</button>
<button id="divide" class="operator" onclick="op='/'">:</button>
</div>
<input id="num2" />
<button onclick="func()">равняется...</button>
<p id="result"></p>
<script>
var op; //выбранный оператор
function func() {
var result;
var num1 = Number(document.getElementById("num1").value);
var num2 = Number(document.getElementById("num2").value);
switch (op) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
if (num2) {
result = num1 / num2;
} else {
result = 'бесконечность';
}
break;
default:
result = 'выберите операцию';
}
document.getElementById("result").innerHTML = result;
}
</script>
В отдельной функции для каждой операции, смысла нет - потому что при смене операции в интерфейсе, в алгоритме меняется всего одно действие... и если мы разделим логику на 4 функции, то не сможем избежать дублирования кода остальных, общих действий (нарушим принцип DRY).
Решение через switch
- в принципе, самое простое (исключая вариант eval()
) и распространенное.
"Лапшу" if..else if
лучше не использовать: есть негласное правило, ограничивающее использование такой конструкции тремя вариантами - а у нас их четыре. Да, читаемость не сильно пострадает от еще одного else if
, но абсолютно незачем "ползать по краю", когда можно написать код чисто.
Пример с использованием современных возможностей JavaScript:
document.addEventListener('DOMContentLoaded', () => {
const [inpA, ops, inpB, btnCalc, inpRes] =
Array.from(document.querySelectorAll('.calc > *'));
for (let op of ops.children)
op.addEventListener('click', selectOp);
btnCalc.addEventListener('click', calc);
function selectOp() {
for (let op of this.parentElement.children)
op.classList.remove('active');
this.classList.add('active');
}
function calc() {
let [a, b, result] = [+inpA.value, +inpB.value, 0];
if (!isFinite(a) || !isFinite(b))
return inpRes.value = 'Неверный ввод';
inpA.value = a;
inpB.value = b;
const selectedOp = document.querySelector('.calc [data-op].active');
switch (selectedOp.dataset.op) {
case '+': result = a + b; break;
case '-': result = a - b; break;
case '∗': result = a * b; break;
case '÷': result = a / b;
}
inpRes.value = result;
}
});
.calc {
display: flex; flex-flow: column nowrap;
align-items: stretch;
max-width: 300px;
font: 18px monospace; }
.calc * { font: inherit; outline: none; }
.calc > * + * { margin-top: 0.5rem; }
.calc div {
display: flex; flex-flow: row nowrap;
justify-content: space-between;
padding: 0 1px; }
.calc [data-op] { width: calc(25% - 8px); }
.calc [data-op]::before,
.calc button {
content: attr(data-op);
display: inline-block;
width: 100%;
font-size: 1.4rem; line-height: 1.4rem;
text-align: center;
border: none;
border-radius: 3px;
transition: box-shadow 0.15s linear;
box-shadow: 0 0 0 1px #ccc;
background: #eee;
cursor: pointer; }
.calc [data-op]:hover::before,
.calc button:hover { box-shadow: 0 0 0 1px #7af; }
.calc [data-op].active::before { background: #aea; }
.calc [readonly] { border: none; text-align: center; }
<div class="calc">
<input type="number">
<div>
<span data-op="+" class="active"></span>
<span data-op="-"></span>
<span data-op="∗"></span>
<span data-op="÷"></span>
</div>
<input type="number">
<button>=</button>
<input readonly>
</div>
Завалялся у меня пример калькулятора, старенький, не до конца написан, но думаю, что логику Вы поймёте и что-то для себя найдёте.
Codepen
class Calculator {
constructor(node) {
this.node = node;
if (!this.node) return;
this.onPanelItemClick = this.onPanelItemClick.bind(this);
this.displayOnBoard = this.displayOnBoard.bind(this);
this.actionOnNumber = this.actionOnNumber.bind(this);
this.numbersPanel = this.node.querySelector(".calculator__panel");
this.board = this.node.querySelector(".calculator__window-calculations");
this.answer = this.node.querySelector(".calculator__window-answer");
this.numbersPanel.addEventListener("click", this.onPanelItemClick, false);
}
onPanelItemClick(event) {
const item = event.target.closest(".calculator__panel-item");
if (!item) return;
if (item.hasAttribute("data-number")) {
this.displayOnBoard(item.getAttribute("data-number"));
} else {
this.actionOnNumber(item.textContent);
}
}
displayOnBoard(number) {
this.board.textContent += number;
}
actionOnNumber(action) {
if (action !== "=" && action !== "c") {
this.board.textContent += action;
} else if (action === "=") {
this.answer.textContent = eval(this.board.textContent);
} else if (action === "c") {
this.board.textContent = "";
}
}
}
new Calculator(document.querySelector(".calculator"));
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: Open sans, sans-serif;
background: #e5e5e5;
}
.container {
position: absolute;
width: 500px;
height: 828px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.calculator__window {
padding: 33px 37px;
background: #fff;
text-align: right;
min-height: 180px;
}
.calculator__window-calculations {
font-size: 1.875rem;
min-height: 34px;
}
.calculator__window-answer {
font-size: 4.375rem;
}
.calculator__panel {
display: flex;
flex-wrap: wrap;
}
.calculator__panel-item {
display: flex;
align-items: center;
justify-content: center;
width: 125px;
height: 125px;
color: #fff;
font-size: 1.563rem;
cursor: pointer;
}
.calculator__panel-item:hover,
.calculator__panel-item:focus {
box-shadow: inset 0px 0px 10px rgba(0, 0, 0, 0.5);
}
.calculator__panel-item-large {
width: 250px;
}
.calculator__panel-item:first-child {
background: #0f266b;
}
.calculator__panel-item:nth-child(2) {
background: #0c2369;
display: flex;
flex-direction: column;
}
.calculator__panel-item:nth-child(3) {
background: #0c2263;
}
.calculator__panel-item:nth-child(4) {
background: #cf066d;
}
.calculator__panel-item:nth-child(5) {
background: #21479f;
}
.calculator__panel-item:nth-child(6) {
background: #2e54ab;
}
.calculator__panel-item:nth-child(7) {
background: #3f67c4;
}
.calculator__panel-item:nth-child(8) {
background: #d62480;
}
.calculator__panel-item:nth-child(9) {
background: #2e54ab;
}
.calculator__panel-item:nth-child(10) {
background: #3b5fb3;
}
.calculator__panel-item:nth-child(11) {
background: #4d6fbf;
}
.calculator__panel-item:nth-child(12) {
background: #d63a8a;
}
.calculator__panel-item:nth-child(13) {
background: #3f67c4;
}
.calculator__panel-item:nth-child(14) {
background: #4b71c9;
}
.calculator__panel-item:nth-child(15) {
background: #5579cf;
}
.calculator__panel-item:nth-child(16) {
background: #d94e95;
}
.calculator__panel-item:nth-child(17) {
background: #577bcf;
}
.calculator__panel-item:nth-child(18) {
background: #6489de;
}
.calculator__panel-item:last-child {
background: #de64a2;
}
<div class="container">
<div class="calculator">
<div class="calculator__window">
<div class="calculator__window-calculations"></div>
<div class="calculator__window-answer"></div>
</div>
<div class="calculator__panel">
<div class="calculator__panel-item" data-type="delete">c</div>
<div class="calculator__panel-item">
<span>+</span>
<span>-</span>
</div>
<div class="calculator__panel-item" data-type="remainder">%</div>
<div class="calculator__panel-item" data-type="division">/</div>
<div class="calculator__panel-item" data-number="7">7</div>
<div class="calculator__panel-item" data-number="8">8</div>
<div class="calculator__panel-item" data-number="9">9</div>
<div class="calculator__panel-item" data-type="multiplication">*</div>
<div class="calculator__panel-item" data-number="4">4</div>
<div class="calculator__panel-item" data-number="5">5</div>
<div class="calculator__panel-item" data-number="6">6</div>
<div class="calculator__panel-item" data-type="subtraction">-</div>
<div class="calculator__panel-item" data-number="1">1</div>
<div class="calculator__panel-item" data-number="2">2</div>
<div class="calculator__panel-item" data-number="3">3</div>
<div class="calculator__panel-item" data-type="addition">+</div>
<div class="calculator__panel-item calculator__panel-item-large" data-number="0">0</div>
<div class="calculator__panel-item" data-type="dot">.</div>
<div class="calculator__panel-item" data-type="equally">=</div>
</div>
</div>
</div>
Можно сделать чуточку красивее и проще. Код не мой, но я его рассматривал, когда начинал изучать js.
<head>
<meta charset="utf-8" />
<title>Калькулятор</title>
<style type="text/css">
#calculator * {font-size: 16px;}
#calculator table {border: solid 3px silver; border-spacing: 3px; background-color: #EEE; }
#calculator table td {border-spacing: 3px;}
input.display {width: 166px; text-align: right;}
td.buttons {border-top: solid 1px silver;}
input[type= button] {width: 40px; height: 30px;}
</style>
</head>
<body>
<form name="calc" id="calculator">
<table>
<tr>
<td>
<input type="text" name="input" size="16" class="display">
</td>
</tr>
<tr>
<td class="buttons">
<input type="button" name="one" value="1" OnClick="calc.input.value += '1'">
<input type="button" name="two" value="2" OnClick="calc.input.value += '2'">
<input type="button" name="three" value="3" OnClick="calc.input.value += '3'">
<input type="button" name="add" value="+" OnClick="calc.input.value += '+'">
<br>
<input type="button" name="four" value="4" OnClick="calc.input.value += '4'">
<input type="button" name="five" value="5" OnClick="calc.input.value += '5'">
<input type="button" name="six" value="6" OnClick="calc.input.value += '6'">
<input type="button" name="sub" value="-" OnClick="calc.input.value += '-'">
<br>
<input type="button" name="seven" value="7" OnClick="calc.input.value += '7'">
<input type="button" name="eight" value="8" OnClick="calc.input.value += '8'">
<input type="button" name="nine" value="9" OnClick="calc.input.value += '9'">
<input type="button" name="mul" value="x" OnClick="calc.input.value += '*'">
<br>
<input type="button" name="clear" value="c" OnClick="calc.input.value = ''">
<input type="button" name="zero" value="0" OnClick="calc.input.value += '0'">
<input type="button" name="doit" value="=" OnClick="calc.input.value = eval(calc.input.value)">
<input type="button" name="div" value="/" OnClick="calc.input.value += '/'">
</td>
</tr>
</table>
</form>
</body>
Я, правда, слабо понимаю какое применение у таких калькуляторов на практике, т.к. во-первых нет проверки вводимых символов (нужно ограничить ввод), нет проверки на ошибки (например, деление на ноль), нет десятичного разделителя.
Виртуальный выделенный сервер (VDS) становится отличным выбором
Решил защитить свою бд и подключить аутентификацию для удалённого доступаНо не смог найти информацию об аутентификации через MongoClient, только...
Хочу отправить форму в телеграм прямо из js файлаВо всем этом новичок
Подскажите, на сайте установлен fullpagejs для постраничного скролла
Есть ссылка на изображение, хочу получить его и загрузить в вк для отправкиТекущий код: