Калькулятор, по определению, используется для выполнения математических вычислений, в частности, небольшое электронное устройство с клавиатурой и визуальным дисплеем. Этот расчет варьируется от базовых операций, таких как сложение, вычитание, деление и умножение, до сложных математических операций, таких как функции косинуса, синуса и логарифмические функции.
С развитием технологий мы теперь можем создавать калькуляторы и использовать их прямо в наших браузерах.
В этом уроке мы создадим базовый калькулятор, который мы сможем использовать прямо в нашем браузере.
Понимание задачи
Калькулятор, который мы будем создавать, сможет выполнять основные операции, такие как сложение, вычитание, деление, а также умножение. Мы разделим нашу работу на 2 части: интерфейс (интерфейс калькулятора) и логика (использование Javascript).
Структура кода
Наш код будет разделен на 2 части. Внешний интерфейс (реализованный с использованием HTML и TailwindCSS) и логика (с использованием JavaScript)
Не отнимая слишком много времени, давайте сделаем это.
Внешний интерфейс (HTML и TailwindCSS)
Что касается пользовательского интерфейса, мы просто разделим его на 2 части: экран дисплея и клавиатуру.
Вот как выглядит код,
<body class="bg-slate-400 text-[#3651c4] flex items-center justify-center min-h-screen"> <main class="w-full max-w-md select-none px-4 md:px-0"> <div class="flex flex-col items-center gap-3 font-bold"> <!-- Display Screen --> <div class="w-full h-28 sm:h-32 bg-white rounded-lg mt-5 md:mt-0 flex flex-col justify-evenly items-end pr-2"> <div class="place-self-center py-1 text-xs md:text[1rem]">Bradon ! Your Coding Buddy😎</div> <div id="previous-operation"></div> <div id="current-operation" class=" text-2xl md:text-3xl font-semibold" ></div> </div> <!-- Keyboard pad container --> <div class="bg-white text-xl w-full p-1 rounded-lg"> <!-- Clear and DEL--> <div class="flex justify-around items-center my-5 [&>*]:px-4 [&>*]:py-1 [&>*]:rounded [&>*:active]:scale-95"> <button id="clear" class="text-white bg-red-600">Clear</button> <button id="delete" class="border border-black text-black">DEL</button> </div> <div class="grid grid-cols-12"> <!-- Numeric pad --> <div class="number col-span-9 grid grid-cols-3 gap-2 [&>*:hover]:bg-blue-900 [&>*]:rounded [&>*:hover]:text-white [&>*:active]:scale-90"> <button data-number>7</button> <button data-number>8</button> <button data-number>9</button> <button data-number>4</button> <button data-number>5</button> <button data-number>6</button> <button data-number>1</button> <button data-number>2</button> <button data-number>3</button> <button data-number>0</button> <button data-number>00</button> <button data-number>.</button> </div> <!-- Symbols--> <div class="basic-operations col-span-3 grid grid-cols-2 [&>*]:py-5 [&>*]:px-2.5 [&>*]:sm:px-6 gap-2 [&>*:hover]:bg-blue-900 [&>*]:rounded [&>*:hover]:text-white [&>*:active]:scale-90"> <button data-operation="/">÷</button> <button data-operation="*">x</button> <button data-operation="-">-</button> <button data-operation="+">+</button> <button data-bracket>(</button> <button data-bracket>)</button> <button id="equal" class="col-span-2 bg-[#3651c4] text-white">=</button> </div> </div> </div> </div> </main> <script src="./main.js"></script> </body>
- Экран дисплея
<div class="w-full h-28 sm:h-32 bg-white rounded-lg mt-5 md:mt-0 flex flex-col justify-evenly items-end pr-2"> <div class="place-self-center py-1 text-xs md:text[1rem]">Bradon ! Your Coding Buddy😎</div> <div id="previous-operation"></div> <div id="current-operation" class=" text-2xl md:text-3xl font-semibold" ></div> </div>
Экран дисплея представляет собой контейнер (Flex-контейнер) с flex-направлением flex-col
, шириной w-full
и гибкой высотой h-28
на экране мобильного устройства и sm:h-32
на маленьких экранах и выше.
Внутри контейнера у нас есть два основных div, и у этих двух div есть идентификаторы, у нас есть один div с id="previous-operation"
, а другой с id="current-operation"
.
Контейнер с id="previous-operation" отвечает за отображение различных входных данных пользователя, в то время как контейнер с id="current-operation" отвечает за отображение результата вычисления
Поскольку контейнер с id="current-operation" отвечает за отображение результатов, мы присвоили его текстовому содержимому font-size
из text-2xl
на мобильных экранах и text-3xl
на средних экранах и выше.
Это в значительной степени все для экрана дисплея.
- Клавиатура
<div class="bg-white text-xl w-full p-1 rounded-lg"> <!-- Clear and DEL--> <div class="flex justify-around items-center my-5 [&>*]:px-4 [&>*]:py-1 [&>*]:rounded [&>*:active]:scale-95"> <button id="clear" class="text-white bg-red-600">Clear</button> <button id="delete" class="border border-black text-black">DEL</button> </div> <div class="grid grid-cols-12"> <!-- Numeric pad --> <div class="number col-span-9 grid grid-cols-3 gap-2 [&>*:hover]:bg-blue-900 [&>*]:rounded [&>*:hover]:text-white [&>*:active]:scale-90"> <button data-number>7</button> <button data-number>8</button> <button data-number>9</button> <button data-number>4</button> <button data-number>5</button> <button data-number>6</button> <button data-number>1</button> <button data-number>2</button> <button data-number>3</button> <button data-number>0</button> <button data-number>00</button> <button data-number>.</button> </div> <!-- Symbols--> <div class="basic-operations col-span-3 grid grid-cols-2 [&>*]:py-5 [&>*]:px-2.5 [&>*]:sm:px-6 gap-2 [&>*:hover]:bg-blue-900 [&>*]:rounded [&>*:hover]:text-white [&>*:active]:scale-90"> <button data-operation="/">÷</button> <button data-operation="*">x</button> <button data-operation="-">-</button> <button data-operation="+">+</button> <button data-bracket>(</button> <button data-bracket>)</button> <button id="equal" class="col-span-2 bg-[#3651c4] text-white">=</button> </div> </div> </div>
По сути, в этом разделе мы разграничили разные части: у нас есть Clear и DEL, цифровая клавиатура и, наконец, у нас есть символы.
- Очистить и УДАЛИТЬ
<div class="flex justify-around items-center my-5 [&>*]:px-4 [&>*]:py-1 [&>*]:rounded [&>*:active]:scale-95"> <button id="clear" class="text-white bg-red-600">Clear</button> <button id="delete" class="border border-black text-black">DEL</button> </div>
Это две кнопки с идентификаторами, описывающими их функции: id="clear"
для Очистить и id="delete
' для DEL.
Мы придали им общий стиль, используя свойство [&›*] из TailwindCSS.
Если вы привыкли к моим постам, то наверняка знаете значение [&>*]
в tailwindcss.
Но если вы новичок, свойство [&›*] просто означает "выбрать каждый дочерний элемент по отдельности", что позволяет нам применять одни и те же свойства стиля ко всем непосредственным дочерним элементам. .
Для каждой из кнопок мы дали им внутренний отступ из px-4
padding-block из py-1
, радиус границы из rounded
, а также придали эффект нажатия, используя [&>*:active]:scale-95
- Цифровой блок
<!-- Numeric pad --> <div class="number col-span-9 grid grid-cols-3 gap-2 [&>*:hover]:bg-blue-900 [&>*]:rounded [&>*:hover]:text-white [&>*:active]:scale-90"> <button data-number>7</button> <button data-number>8</button> <button data-number>9</button> <button data-number>4</button> <button data-number>5</button> <button data-number>6</button> <button data-number>1</button> <button data-number>2</button> <button data-number>3</button> <button data-number>0</button> <button data-number>00</button> <button data-number>.</button> </div>
мы используем аналогичный подход к разделу Clear и DEL, чтобы придать стиль цифровой панели. Мы присвоили им индивидуальный фоновый цвет bg-blue-900
, радиус границы rounded
и эффект щелчка, используя active:scale-90
.
Стоит сказать, что основной контейнер, в котором находится эта цифровая панель и символ, был сделан контейнером сетки с 12 столбцами с использованием grid grid-cols-12
.
И мы выделили 9 столбцов для цифровой панели (вы можете видеть col-span-9
) и выделили 3 столбца для раздела символов.
- Символ
<!-- Symbols--> <div class="basic-operations col-span-3 grid grid-cols-2 [&>*]:py-5 [&>*]:px-2.5 [&>*]:sm:px-6 gap-2 [&>*:hover]:bg-blue-900 [&>*]:rounded [&>*:hover]:text-white [&>*:active]:scale-90"> <button data-operation="/">÷</button> <button data-operation="*">x</button> <button data-operation="-">-</button> <button data-operation="+">+</button> <button data-bracket>(</button> <button data-bracket>)</button> <button id="equal" class="col-span-2 bg-[#3651c4] text-white">=</button> </div>
Здесь особо нечего сказать, все стили, примененные здесь, изначально использовались в других разделах.
Логика (JavaScript)
Чтобы наш калькулятор работал в Интернете, мы использовали язык программирования Javascript.
Я выбираю подход с одним классом, создавая класс с различными методами, которые выполняют разные функции в зависимости от необходимости.
class Computation { constructor (previousOperation, currentOperation){ this.previousOperation = previousOperation; this.currentOperation = currentOperation; this.clear() } clear(){ previousOperation.innerText = '0' currentOperation.innerText = '0' } updateDisplay(value){ if (previousOperation.innerText === '0') previousOperation.innerText = value.toString() else previousOperation.innerText = previousOperation.innerText.toString() + value.toString() } delete(){ previousOperation.innerText = previousOperation.innerText.slice(0, -1) } result(){ let result = previousOperation.innerText.split('') let cleanResult = result.map(number => { if (number === 'x'){ return '*' } if(number === '÷') return '/' else return number; }); result = cleanResult.join('') console.log(eval(result)) currentOperation.innerText = eval(result) } } const numbers = document.querySelectorAll('[data-number]') const operation = document.querySelectorAll('[data-operation]') const bracket = document.querySelectorAll('[data-bracket]') const specialOperation = document.querySelectorAll('[data-special-operation]') const deleteButton = document.getElementById('delete') const equal = document.getElementById('equal') const clear = document.getElementById('clear') const previousOperation = document.getElementById('previous-operation') const currentOperation= document.getElementById('current-operation') const computation = new Computation (previousOperation, currentOperation) numbers.forEach(button => { button.addEventListener('click', ()=>{ let value = button.innerText console.log(value); computation.updateDisplay(value); }) }) operation.forEach(button =>{ button.addEventListener('click', ()=>{ let operant = button.innerText computation.updateDisplay(operant) }) }) deleteButton.addEventListener ('click', ()=> { computation.delete() }) equal.addEventListener('click', ()=>{ computation.result() }) clear.addEventListener('click', ()=>{ computation.clear() }) bracket.forEach(button => { button.addEventListener('click', ()=>{ let brackets = button.innerText computation.updateDisplay(brackets) }) })
Наш большой класс называется Computation, этот класс имеет различные методы, а именно
- clear(): чтобы очистить и сбросить предыдущую операцию и текущую операцию до нуля
- updateDisplay(): как следует из названия, он отвечает за обновление содержимого предыдущей и текущей операций.
- delete(): помогает удалить последний ввод на уровне предыдущей операции.
- result(): выполняет все необходимые операции, затем передает свой результат pt updateDisplay() для обновления содержимого текущей операции.
Мы использовали функцию JavaScript eval(), чтобы упростить наши вычисления.
Возможно, вы захотите узнать больше о методе eval() в Javascript.
После нашего класса Computation мы сделали несколько объявлений, мы сослались на все различные идентификаторы и атрибуты в HTML на некоторые константы в файле Javascript, а затем, когда вперед, добавили прослушиватели событий к каждой кнопке и передали им соответствующий метод для соответствующих вычислений.
И это почти все для этого урока
Заключение
Мы только что создали полностью адаптивный, красивый и функциональный базовый веб-калькулятор.
Это определенно то, что вы можете добавить в свое портфолио или свой следующий проект, который может потребовать некоторых расчетов.
Вы можете получить предварительный просмотр на Codepen и получить исходный код на GitHub.
Не стесняйтесь поделиться со мной, если вы смогли пройти обучение на своей стороне.
Если у вас есть какие-либо опасения или предложения, не стесняйтесь поднимать их! 😊
До встречи! 👋