2022-09-08 계산기_클론_1

계산기

이렇게 생긴 계산기를 Html, CSS, JS를 이용해서 만들어보자.

유튜버 수코딩님의 강의 영상을 보고서 따라 했다.

클론 코딩을 하면서 배운 점을 정리해보자.


1. 파일

보관 중인 Github 주소 :

index.html

<!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" />
    <title>Calculator</title>
    <link rel="stylesheet" href="style.css" />
    <script src="main.js" defer></script>
  </head>
  <body>
    <div class="calculator">
      <form class="forms">
        <input type="text" name="output" readonly />
        <input class="clear" type="button" value="C" onclick="makeClear()"/>
        <input class="operation" type="button" value="/" onclick="makeFormula(this);"/>
        <input type="button" value="1" onclick="makeFormula(this);" />
        <input type="button" value="2" onclick="makeFormula(this);"/>
        <input type="button" value="3" onclick="makeFormula(this);"/>
        <input class="operation" type="button" value="*" onclick="makeFormula(this);"/>
        <input type="button" value="4" onclick="makeFormula(this);"/>
        <input type="button" value="5" onclick="makeFormula(this);"/>
        <input type="button" value="6" onclick="makeFormula(this);"/>
        <input class="operation" type="button" value="+" onclick="makeFormula(this);"/>
        <input type="button" value="7" onclick="makeFormula(this);"/>
        <input type="button" value="8" onclick="makeFormula(this);"/>
        <input type="button" value="9" onclick="makeFormula(this);"/>
        <input class="operation" type="button" value="-" onclick="makeFormula(this);"/>
        <input class="dot" type="button" value="." onclick="makeFormula(this);"/>
        <input type="button" value="0" onclick="makeFormula(this);"/>
        <input class="operation result" type="button" value="=" onclick="makeResult()"/>
      </form>
    </div>
  </body>
</html>Code language: HTML, XML (xml)

style.css

:root{
    /* color */
    --red-color : #ea6d5a;
    --orange-color: #f4b23e;
    --green-color: #2f6d1c;
    --background-color: #1f1f1f;
    --calculator-color: #ccc;
    --black-color: #333;

    /* size */
    /* --padding : 12px; */
    /* margin: 12px; */

    /* font size */
    /* --font-large: 24px; */
    /* --font-medium: 20px; */
    /* --font-small: 18px; */
    /* --font-micro: 16px; */

}
* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

body {
    background-color: var(--background-color);
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
}

body .calculator {
    border: 1px solid var(--black-color);
    width: 287px;
    background-color: var(--calculator-color);
    padding : 5px;
}

body .calculator .forms {
    display: grid;
    grid-template-columns: repeat(4, 65px);
    grid-auto-rows : 65px;
    /* 4번 반복 65px */
    grid-gap: 5px;
}

body .calculator .forms > input {
    border : 2px solid var(--black-color);
    cursor: pointer;
    text-align: center;
    font-size: 19px;
}

body .calculator .forms > input:hover {
    box-shadow: 1px 1px 2px var(--black-color);

}

body .calculator .forms > input[type='text'] {
    grid-column:span 4;
    cursor:default;
    text-align: right;
    padding: 0 10px;
}

body .calculator .forms > input[type='text']:hover {
    box-shadow: none;
}

body .calculator .forms .clear {
    background-color: var(--red-color);
    grid-column:span 3;
}

body .calculator .forms .operation {
    background-color: var(--orange-color);
}

body .calculator .forms .result {
    grid-column: span 2;
}

body .calculator .forms .dot {
    background-color: var(--green-color);
}Code language: CSS (css)

main.js

var output = document.querySelector("body .forms input[name='output']");
// output을 전역변수로 선언하면 오류가 발생하는 이유 : 지금 head에 위치한 script tag를 읽고 있다. 즉 body tag 아래에 위치한 태그들은 아직 생성되지 않았다.
// <script ... ></script>에 defer를 추가하면 해결할 수 있다.

function makeFormula(self) {
//   const output = documen지.querySelector("body .forms input[name=output]");
  output.value += self.value;
}
function makeClear() {
//   const output = document.querySelector("body .forms input[name=output]");
  output.value = "";
}
function makeResult() {
//   const output = document.querySelector("body .forms input[name=output]");
  output.value = eval(output.value);
}Code language: JavaScript (javascript)

CSS 단위

참고!

https://webclub.tistory.com/356


height: 100vh

height: 100vh;가 필요한 이유.

없으면 이렇게 된다.

그 이유에 대하여 알아보면 …

별도로 body의 높이를 지정하지 않으면 위와 같이 된다.

높이의 여유공간 없이 붙여버린다.

그래서는 align-items를 사용한 의미가 없어진다.

그래서 뷰포트를 기준으로 뷰포트의 높이값이나 그의 유사한 높이값의 공간을 확보하기 위해서 100vh를 사용했다.

vh, vw 예시)
뷰포트의 높이값이 900px -> 1vh는 9px
뷰포트의 너비값이 750px -> 1vw는 7.5pxCode language: CSS (css)

반응형 웹페이지를 만들 때 %를 많이 사용한다.

이때 %는 부모의 영향을 받는다.

부모의 영향 없이 순수히 뷰포트를 기준으로 상대적인 크기를 설정할 때 사용할 수 있다.

출처: https://webclub.tistory.com/356


grid-template-columns

grid에서 가로를 구성하는 새로운 방식.

<style>
    ...
    #grid{
        display: grid;
        grid-template-columns: 150px 1fr;
    }
    ...
</style>Code language: HTML, XML (xml)

이전에 사용한 방식 :

body .calculator .forms {
    display: grid;
    grid-template-columns: repeat(4, 65px);
    grid-auto-rows : 65px;
    /* 4번 반복 65px */
    grid-gap: 5px;
}Code language: CSS (css)

가로를 65px로 나눈 4개의 칸으로 나눈다.


grid-column: span 4

body .calculator .forms > input[type='text'] {
grid-column:span 4;
cursor:default;
text-align: right;
padding: 0 10px;
}Code language: CSS (css)

일전에 나눈 가로 4칸 중 4칸 모두를 차치하도록 설정한다.


grid 간격

body .calculator .forms {
    display: grid;
    grid-template-columns: repeat(4, 65px);
    grid-auto-rows : 65px;
    /* 4번 반복 65px */
    grid-gap: 5px;
}Code language: CSS (css)

grid-gap으로 칸 사이에 간격을 설정할 수 있다.


cursor: pointer

마우스를 올리면 손가락이 보이게 만들기.

body .calculator .forms > input {
    ...
    cursor: pointer;
        ...
}

그림자 넣기

body .calculator .forms > input:hover {
    box-shadow: 1px 1px 2px var(--black-color);
        //순서대로 오른쪽 아래쪽 번짐효과 색상이다.
}Code language: JavaScript (javascript)


script tag에 defer가 필요한 이유

<head>
        ...
    <script src="main.js"></script>
  </head>
  <body>
    <div class="calculator">
      <form class="forms">
        <input type="text" name="output" readonly />
                ...Code language: HTML, XML (xml)

index.html의 일부분이다.

보면 컴퓨터는 순서상 script 태그를 읽고서 나중에 body 태그 아래 input를 읽는다.

그렇기에 아래와 같이 JS 코드를 작성하면 오류가 생긴다.

var output = document.querySelector("body .forms input[name='output']");
// output을 전역변수로 선언하면 오류가 발생하는 이유 : 지금 head에 위치한 script tag를 읽고 있다. 즉 body tag 아래에 위치한 태그들은 아직 생성되지 않았다.
// <script ... ></script>에 defer를 추가하면 해결할 수 있다.

function makeFormula(self) {
  output.value += self.value;
}
function makeClear() {
  output.value = "";
}
function makeResult() {
  output.value = eval(output.value);
}Code language: JavaScript (javascript)

이유는 해당 main.js를 읽는 당시에는 아직 body .forms input[name=’output’]에 해당하는 input 태그가 생성되지 않았기 때문이다.

그렇기에 전역 변수를 생성할 수 없었다.

이와 같은 문제를 해결하기 위해선 아래와 같이 코드를 수정한다.

<script src="main.js" defer></script>Code language: HTML, XML (xml)

defer라는 속성을 추가하면 해결할 수 있다.


댓글 남기기