Калькулятор, по определению, используется для выполнения математических вычислений, в частности, небольшое электронное устройство с клавиатурой и визуальным дисплеем. Этот расчет варьируется от базовых операций, таких как сложение, вычитание, деление и умножение, до сложных математических операций, таких как функции косинуса, синуса и логарифмические функции.

С развитием технологий мы теперь можем создавать калькуляторы и использовать их прямо в наших браузерах.

В этом уроке мы создадим базовый калькулятор, который мы сможем использовать прямо в нашем браузере.

Понимание задачи

Калькулятор, который мы будем создавать, сможет выполнять основные операции, такие как сложение, вычитание, деление, а также умножение. Мы разделим нашу работу на 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>
  1. Экран дисплея
<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 на средних экранах и выше.

Это в значительной степени все для экрана дисплея.

  1. Клавиатура
<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.

Не стесняйтесь поделиться со мной, если вы смогли пройти обучение на своей стороне.

Если у вас есть какие-либо опасения или предложения, не стесняйтесь поднимать их! 😊

До встречи! 👋