기존에 작성했던 Mock-up에 Javascript로 계산기를 구현하여 Calculator를 만들었다. javascript는 코드스테이츠에서 제공받은 js파일에서 구현했고, nightmare 파트는 레퍼런스를 보고 추가했다....😂
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<style>
@import url('https://fonts.googleapis.com/css2?family=Concert+One&family=Press+Start+2P&display=swap');
</style>
<title>Document</title>
</head>
<body>
<div class="calculator">
<div class = "menu">
<div class ="display">
<div class="calculator__display--for-advanced">0</div>
</div>
<div class="buttonPad">
<div class="buttonLine">
<button class = "ac">AC </button>
<button class ="enter">Enter</button>
</div>
<div class="buttonLine">
<button class="number">7</button>
<button class="number">8</button>
<button class="number">9</button>
<button class="operator">+</button>
</div>
<div class="buttonLine">
<button class="number">4</button>
<button class="number">5</button>
<button class="number">6</button>
<button class="operator">-</button>
</div>
<div class="buttonLine">
<button class="number">1</button>
<button class="number">2</button>
<button class="number">3</button>
<button class="operator">*</button>
</div>
<div class="buttonLine">
<button class="number num0">0</button>
<button class="decimal">.</button>
<button class="operator">/</button>
</div>
</div>
</div>
</div>
<script src='./script.js'></script>
</body>
</html>
.calculator {
width: 350px;
height: 550px;
background: linear-gradient(#ffc8dd , #bde0fe);
align-items: center;
justify-content: center;
display: flex;
flex-direction: column;
border-top: 2px solid rgba(250, 250, 250, 0.795);
border-left: 2px solid rgba(250, 250, 250, 0.733);
box-shadow: 10px 20px 30px rgba(0, 0, 0, 0.15);
}
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
padding: 0;
background:linear-gradient( #bde0fe, #ffc8dd );
}
.display{
background-color: #fff4f8;
display: flex;
justify-content: flex-end;
height: 100px;
font-size: 30px;
color: #cdb4db;
margin: 0 14px 10px 14px;
padding: 10px 12px;
}
.buttonPad{
display: flex;
flex-direction: column;
}
.buttonLine{
margin: 10px;
display: flex;
}
button {
margin: 0px 7px;
width: 60px;
height: 60px;
font-size: 30px;
color:#ffffff;
border-radius: 50%;
border:none;
background-color: #cdb4db;
box-shadow: 0px 5px 0px 0px #b157e68e;
transition-duration: 0.3s;
}
button:hover .paw{
margin-top: 1px;
margin-bottom: 1px;
}
button:active {
box-shadow: 0px 0px;
}
.operator:hover{
box-shadow: 0px 0px 0px 0px #b157e68e;
}
.number:hover{
box-shadow: 0px 0px 0px 0px #b157e68e;
}
.decimal:hover{
box-shadow: 0px 0px 0px 0px #b157e68e;
}
.num0{
flex: 1;
border-radius: 10px;
}
.num0:hover{
box-shadow: 0px 0px 0px 0px #b157e68e;
}
.ac {
width: 50%;
background-color: #ffafcc;
box-shadow: 0px 5px 0px 0px #f893b8;
color:#fff;
border-radius: 10px;
}
.ac:hover{
box-shadow: 0px 0px 0px 0px #f893b8;
}
.enter {
width: 50%;
border-radius: 10px;
background-color: #a2d2ff;
box-shadow: 0px 5px 0px 0px #76b9f8;
}
.enter:hover {
box-shadow: 0px 0px 0px 0px #76b9f8;
}
* {
box-sizing: border-box;
border-radius: 10px;
font-family: 'Concert One', cursive;
}
const calculator = document.querySelector('.calculator'); // calculator 엘리먼트와, 그 자식 엘리먼트의 정보
const buttons = calculator.querySelector('.buttonPad'); // calculator__keys 엘리먼트와, 그 자식 엘리먼트의 정보
function calculate(n1, operator, n2) {
let result = 0;
n1 = Number(n1);
n2 = Number(n2);
if(operator === '+'){
result = n1 + n2;
}
if(operator === '-'){
result = n1 - n2;
}
if(operator === '*'){
result = n1 * n2;
}
if(operator === '/'){
result = n1 / n2;
}
return String(result);
}
const display = document.querySelector('.calculator__display--for-advanced'); // calculator__display 엘리먼트와, 그 자식 엘리먼트의 정보
let firstNum, operatorForAdvanced, previousKey, previousNum;
buttons.addEventListener('click', function (event) {
// 버튼을 눌렀을 때 작동
const target = event.target; // 클릭된 HTML 엘리먼트의 정보가 저장되어 있다.
const action = target.classList[0]; // 클릭된 HTML 엘리먼트에 클레스 정보를 가져온다.
const buttonContent = target.textContent; // 클릭된 HTML 엘리먼트의 텍스트 정보를 가져온다.
// Advanced Challenge & Nightmare
if (target.matches('button')) {
if (action === 'number') {
if(display.textContent === '0' || previousKey === 'operator' || previousKey === 'calculate'){ //화면이 0이거나 직전에 연산자나 enter를 눌렀다면,
display.textContent = buttonContent; //첫 숫자 입력 or 연산자 또는 calculate을 누른 다음이라면 그 다음 계산할 숫자나 pr
}else{
display.textContent = display.textContent + buttonContent; //숫자를 연달아 출력
}
previousKey = 'number';
}
if (action === 'operator') {
if(firstNum && operatorForAdvanced && previousKey !== 'operator' && previousKey !== 'calculate'){
//연산자를 누르기 전의 숫자면서, 연산자를 누르면서, 직전 값이 숫자이며 직전 값이 enter도 아니라면
display.textContent = calculate(firstNum, operatorForAdvanced, display.textContent); //연산자를 누르기 전의 숫자 <operator> 화면의 숫자
}
firstNum = display.textContent; //연산자를 누르기 전의 화면의 숫자
console.log(`FirstNum : ${display.textContent}`);
operatorForAdvanced = buttonContent;
previousKey = 'operator';
}
if (action === 'decimal') {
if(!display.textContent.includes('.') && previousKey !== 'operator'){ //Nightmare: 화면의 .를 포함하지 않으면서 이전 값이 연산자가 아니라면(.을 연속으로 눌러도 처음 단 한번만 출력)
display.textContent = display.textContent + '.'; //화면의 숫자 뒤에 .을 출력한다.
}else if(previousKey === 'operator'){ //이전값이 연산자라면(숫자가 아니라면)
display.textContent = '0' + buttonContent; //Nightmare: 정수 부분 없이 . 버튼과 숫자를 눌러서 작동시키는 경우 소수로 나타냄(.5 -> 0.5)
}
previousKey = 'decimal';
}
if (action === 'ac') {
firstNum = undefined;
operatorForAdvanced = undefined;
previousKey = undefined;
previousNum = undefined;
display.textContent = '0';
}
if (action === 'enter') {
if(firstNum){ //firstNum이 있을 때,
if(previousKey === 'calculate') { //Nightmare: 바로 직전에 enter를 눌렀을 때(연산자 버튼 누르기 전 실수로 enter 여러번 눌러도 정상 작동)
display.textContent = calculate(display.textContent, operatorForAdvanced, previousNum); //Nightmare: 화면의 숫자 <opator> 직전값(enter 버튼 여러번 눌렀을 때 직전의 oper랑 숫자 계속 수행)
}else{ //일반적인 계산(Advanced Challenge test때 구현한 코드)
previousNum = display.textContent; //enter 직전의 화면의 숫자
display.textContent = calculate(firstNum, operatorForAdvanced, display.textContent); //연산자를 누르기 전 숫자 <operator> 화면의 숫자
}
}
previousKey = 'calculate';
}
}
});
Reference: 코드스테이츠