сделал простой калькулятор, который складывает, вычитает, умножает и делит. Но как этот код уменьшить? На сколько я понимаю это делается с помощью функций, но я не понимаю как это реализовать.
function plus() {
var num1, num2, result;
num1 = document.getElementById('n1').value;
num1 = parseInt(num1);
num2 = document.getElementById('n2').value;
num2 = Number(num2);
result = num1 + num2;
document.getElementById('out').innerHTML = result;
}
function minus() {
var num1, num2, result;
num1 = document.getElementById('n1').value;
num1 = parseInt(num1);
num2 = document.getElementById('n2').value;
num2 = Number(num2);
result = num1 - num2;
document.getElementById('out').innerHTML = result;
}
function multiply() {
var num1, num2, result;
num1 = document.getElementById('n1').value;
num1 = parseInt(num1);
num2 = document.getElementById('n2').value;
num2 = Number(num2);
result = num1 * num2;
document.getElementById('out').innerHTML = result;
}
function share() {
var num1, num2, result;
num1 = document.getElementById('n1').value;
num1 = parseInt(num1);
num2 = document.getElementById('n2').value;
num2 = Number(num2);
result = num1 / num2;
document.getElementById('out').innerHTML = result;
}
<h1>калкулятор</h1>
<div class="NumAll">
<p class="Num1" >
<input type="text" id="n1">
</p>
<p class="Num2" >
<input type="text" id="n2">
</p>
</div>
<div class="btn">
<button onclick="minus()" >Вычесть</button>
<button onclick="plus()" >Сложить</button>
<button onclick="multiply()" >Умножить</button>
<button onclick="share()" >Делить</button>
</div>
<p class="Res" id="out">Результат</p>
Все четыре функции у вас отличаются лишь операцией. Логично будет сделать функцию, которая получает два числа, тип операции и возвращает результат. А получение и вывод данных прописать лишь в одном месте.
document.querySelector(селектор)
возвращает первый элемент на странице, который будет соответствовать CSS-селектору. Если и его не хочется дублировать везде, можно сделать коротенькую функцию-обертку и для него.
Вынес onclick
из HTML, потому что оно не используется дальше учебных примеров ( https://google.com#q=dont+use+inline+onclick ). Хорошо бы сразу привыкнуть к addEventListener — добавлять обработчики отдельно от HTML.
let inp_1 = first("#n1"), inp_2 = first("#n2"), out = first("#out");
first(".btn").addEventListener("click", function(e) {
let operation = e.target.dataset.oper;
if (!operation) return; // Операция не указана? Значит кликнули не на кнопку.
let a = +inp_1.value; // унарный плюс делает то же, что и Number()
let b = +inp_2.value;
out.textContent = calc(a, operation, b);
});
/***/
function calc(a, oper, b) {
switch (oper) {
case "sub": return a - b;
case "sum": return a + b;
case "mul": return a * b;
case "div": return a / b;
}
}
function first(selector) {
return document.querySelector(selector);
}
<h1>калкулятор</h1>
<div class="NumAll">
<p class="Num1">
<input type="text" id="n1">
</p>
<p class="Num2">
<input type="text" id="n2">
</p>
</div>
<div class="btn">
<button data-oper="sub">Вычесть</button>
<button data-oper="sum">Сложить</button>
<button data-oper="mul">Умножить</button>
<button data-oper="div">Делить</button>
</div>
<p class="Res" id="out">Результат</p>
Можно определить класс с множеством допустимых операторов.
class Calc {
binary_operators = {
'+': (a, b) => a + b,
'-': (a, b) => a - b,
'*': (a, b) => a * b,
'/': (a, b) => a / b,
};
unary_operators = {
'sin': (a) => Math.sin(a),
};
constructor(aEl, bEl, resEl) {
this.aEl = aEl;
this.bEl = bEl;
this.resEl = resEl;
}
initButtons(buttons) {
buttons.forEach(btn => btn.addEventListener('click', () => {
if (btn.dataset.binOperator) {
this.binaryOp(btn.dataset.binOperator);
} else if (btn.dataset.unaryOperator) {
this.unaryOp(btn.dataset.unaryOperator);
}
}));
}
unaryOp(op) {
const operator = this.unary_operators[op];
if (!operator) throw new Error(`Unknown operator ${op}`);
this.resEl.innerText = operator(+this.aEl.value);
}
binaryOp(op) {
const operator = this.binary_operators[op];
if (!operator) throw new Error(`Unknown operator ${op}`);
this.resEl.innerText = operator(+this.aEl.value, +this.bEl.value);
}
}
const calc = new Calc(
document.getElementById('n1'),
document.getElementById('n2'),
document.getElementById('out')
);
calc.initButtons(document.querySelectorAll('.calc-button'));
<h1>Калькулятор</h1>
<div class="NumAll">
<p class="Num1">
<input type="text" id="n1">
</p>
<p class="Num2">
<input type="text" id="n2">
</p>
</div>
<div class="btn">
<button data-bin-operator="-" class="calc-button">Вычесть</button>
<button data-bin-operator="+" class="calc-button">Сложить</button>
<button data-bin-operator="*" class="calc-button">Умножить</button>
<button data-bin-operator="/" class="calc-button">Делить</button>
<button data-unary-operator="sin" class="calc-button">sin(x)</button>
</div>
<p class="Res" id="out">Результат</p>
А это кое-кому похоже нечем было заняться перед концом рабочей недели)
class Calc {
operations = {
'id': (a, b) => b,
'+': (a, b) => a + b,
'-': (a, b) => a - b,
'*': (a, b) => a * b,
'/': (a, b) => a / b,
};
unary_operators = {
'sin': (a) => Math.sin(a),
};
constructor(el) {
this.el = el;
this.resEl = this.el.querySelector('.calc-result');
this.initialize();
this.reset();
}
reset() {
this.resEl.innerText = '0';
this.operandA = 0;
this.operandB = 0;
this.newInputFlag = true;
this.currentOperator = this.operations['id'];
}
#calc() {
const result = this.currentOperator(this.operandA, this.operandB);
this.operandA = result;
this.resEl.innerText = parseFloat(result.toFixed(16));
this.newInputFlag = true;
}
#addDigit(digit) {
if (this.newInputFlag) {
this.resEl.innerText = '';
}
this.resEl.innerText = (this.resEl.innerText + digit).replace(/^0+(\d)/, '$1');
this.newInputFlag = false;
}
#addPoint() {
if (this.newInputFlag) {
this.resEl.innerText = '0';
}
if (-1 === this.resEl.innerText.indexOf('.')) {
this.resEl.innerText = this.resEl.innerText + '.';
this.newInputFlag = false;
}
}
#getResult() {
try {
if (!this.newInputFlag) {
this.operandB = Number(this.resEl.innerText);
}
this.#calc();
} catch (e) {
this.resEl.innerText = 'ЕГГОГ';
}
}
#setOperator(operator) {
if (!this.newInputFlag) {
this.operandB = Number(this.resEl.innerText);
this.#calc();
}
if (!operator) throw new Error(`Unknown operation ${op}`);
this.currentOperator = operator;
}
#initButton(btn) {
btn.addEventListener('click', () => {
switch (btn.dataset.calcType) {
case 'reset': this.reset(); break;
case 'digit': this.#addDigit(btn.dataset.digit); break;
case 'point': this.#addPoint(); break;
case 'result': this.#getResult(); break;
case 'operator': this.#setOperator(this.operations[btn.dataset.calcOp]); break;
}
});
}
initialize() {
this.el.querySelectorAll('.calc-button')
.forEach(btn => this.#initButton(btn));
}
}
const calc = new Calc(document.querySelector('.calc'));
.calc {
border: 3px solid silver;
padding: 1em;
width: 360px;
height: 360px;
margin: 0 auto;
position: relative;
background: #cec;
}
.calc-result {
border: 1px solid silver;
padding: 0.2em;
margin: 0.5em;
background: #aaa;
text-align: right;
line-height: 2em;
font-size: 2em;
white-space: nowrap;
}
table.calc-buttons {
width: 100%;
height: 70%;
}
table.calc-buttons td .calc-button {
width: 100%;
height: 100%;
}
<div class="calc">
<div class="calc-result">0</div>
<table class="calc-buttons">
<tr>
<td>
<button class="calc-button" data-calc-type="reset">C</button>
</td>
<td>
<button class="calc-button" data-calc-type="operator" data-calc-op="/">/</button>
</td>
<td>
<button class="calc-button" data-calc-type="operator" data-calc-op="*">*</button>
</td>
<td>
<button class="calc-button" data-calc-type="operator" data-calc-op="-">-</button>
</td>
</tr>
<tr>
<td>
<button class="calc-button" data-calc-type="digit" data-digit="7">7</button>
</td>
<td>
<button class="calc-button" data-calc-type="digit" data-digit="8">8</button>
</td>
<td>
<button class="calc-button" data-calc-type="digit" data-digit="9">9</button>
</td>
<td rowspan="2">
<button class="calc-button" data-calc-type="operator" data-calc-op="+">+</button>
</td>
</tr>
<tr>
<td>
<button class="calc-button" data-calc-type="digit" data-digit="4">4</button>
</td>
<td>
<button class="calc-button" data-calc-type="digit" data-digit="5">5</button>
</td>
<td>
<button class="calc-button" data-calc-type="digit" data-digit="6">6</button>
</td>
</tr>
<tr>
<td>
<button class="calc-button" data-calc-type="digit" data-digit="1">1</button>
</td>
<td>
<button class="calc-button" data-calc-type="digit" data-digit="2">2</button>
</td>
<td>
<button class="calc-button" data-calc-type="digit" data-digit="3">3</button>
</td>
<td rowspan="2">
<button class="calc-button" data-calc-type="result">=</button>
</td>
</tr>
<tr>
<td colspan="2">
<button class="calc-button" data-calc-type="digit" data-digit="0">0</button>
</td>
<td>
<button class="calc-button" data-calc-type="point">.</button>
</td>
</tr>
</table>
</div>
P.S. eval()
лучше не использовать с связи с безопасностью, но в нашем случаи +document...value
возвратит либо число, либо NaN
.
UPD
Вместо eval
можно использовать синтаксис Function(...)
.
const out = document.getElementById('out');
function calc(operation) {
out.innerHTML = Function(`return (${+document.getElementById('n1').value} ${operation} ${+document.getElementById('n2').value})`)()
}
<h1>калкулятор</h1>
<div class="NumAll">
<p class="Num1">
<input type="text" id="n1">
</p>
<p class="Num2">
<input type="text" id="n2">
</p>
</div>
<div class="btn">
<button onclick="calc('-')">Вычесть</button>
<button onclick="calc('+')">Сложить</button>
<button onclick="calc('*')">Умножить</button>
<button onclick="calc('/')">Делить</button>
</div>
<p class="Res" id="out">Результат</p>
Нужно написать цикл, который перебирает числа от 4 до 37 и выполняет следующие действия:
У меня есть текст, который движется по кругу SVG, и который масштабируется в зависимости от размера окна - Я хочу анимировать текст так, чтобы...