코드캠프 5~6일차!

정희준·2023년 2월 20일
0

한주의 시작!!

베이스캠프를 시작한 지 일주일이 흘렀다! 지난주 금요일에 친구의 부름에 과제만 마치고 후다닥 놀러 나가는 바람에 5일차와 6일차를 같이 쓰게 돼버렸다 ㅎㅎ.. 빼먹지 말자..
자 오늘도 열공 가보자!

🏷 5일차 요약!

  • 인증번호 생성 코드 수정
    4일차때 만들었던 인증번호 타이머 코드에 문제 발생!
    바로 코드 수정 go go!
// html
<!DOCTYPE html>
<html lang="ko">
<head>
    <title>function</title>
    <script src="./06-timer.js"></script>
</head>
<body>
       <input id="target" type="text" placeholder="000000" disabled="true">
       <button id="send" onclick="sendNum()">인증번호 전송</button> 
       <div id="time">3:00</div>
       <button id="finish">인증완료</button>
</body>
</html>

// js
let isStarted = false;

let sendNum = () => {

    if (isStarted === false) {
        // 타이머가 작동중이 아닐떄
        isStarted = true
        document.getElementById("finish").disabled = false
        const token = String(Math.floor(Math.random() * 1000000)).padStart(6, "0")
        document.getElementById("target").value = token
        document.getElementById("target").style.color = `#${token}`
        // document.getElementById("target").style.color = "#" + token 

        let time = 10
        let timer

        timer = setInterval(function () {
            if (time >= 0) {
                let min = Math.floor(time / 60)
                let sec = String(time % 60).padStart(2, "0")
                document.getElementById("time").innerText = min + ":" + sec
                time = time - 1
            } else {
                document.getElementById("finish").disabled = true
                isStarted = false
                clearInterval(timer)
            }

        }, 1000)

    } else {
        // 타이머가 작동중일때

    }

}

4일차 때 인증번호 전송 버튼을 여러 번 누르게 되면 setInterval 함수가 계속 발동되는 문제가 생겼다
그래서 타이머가 작동 중인지 아닌지 판별할 변수를 생성해서 조건을 추가하였고 setInterval을 변수화 시켜서 clearInterval에 담아주어 멈추는 기능까지 생성하여 문제를 해결하였다!

  • 추억의 싸이월드 완성!

    한 주 동안 만들었던 홈 화면과 주크박스 화면 게임 화면을 메뉴 클릭 시 iframe 태그를 이용해 이동할 수 있게 만들고 클릭한 버튼의 css를 변경하였다.
// html 일부
<div class="wrapper__right">
	<div class="wrapper__right__header">
    	<div class="right__header__title">사이좋은 사람들, 싸이월드</div>
        <div class="right__header__setting">사생활보호설정►</div>
    </div>
    <div class="wrapper__right__body">
        <iframe id="contentsFrame" src="./home.html"></iframe>
    </div>
</div>
<div class="navigation">
	<div class="navigation__item" id="menuHome" onclick="menuHome()"></div>
	<div class="navigation__item" id="menuJukebox" onclick="menuJukebox()">쥬크박스</div>
	<div class="navigation__item" id="menuGame" onclick="menuGame()">게임</div>
</div>

//js 
const menuHome = () => {
    document.getElementById("contentsFrame").setAttribute("src","home.html")
    document.getElementById("menuHome").style = "color : black; background-color: white;"
    document.getElementById("menuJukebox").style = "color : white; background-color: #298eb5;"
    document.getElementById("menuGame").style = "color : white; background-color: #298eb5;"
}

const menuJukebox = () => {
    document.getElementById("contentsFrame").setAttribute("src","jukebox.html")
    document.getElementById("menuHome").style = "color : white; background-color: #298eb5;"
    document.getElementById("menuJukebox").style = "color : black; background-color: white;"
    document.getElementById("menuGame").style = "color : white; background-color: #298eb5;"
}

const menuGame = () => {
    document.getElementById("contentsFrame").setAttribute("src","game.html")
    document.getElementById("menuHome").style = "color : white; background-color: #298eb5;"
    document.getElementById("menuJukebox").style = "color : white; background-color: #298eb5;"
    document.getElementById("menuGame").style = "color : black; background-color: white;"
}
  • Final 과제!
    첫 주 프리 캠프 과정의 마지막 과제 한 주간 배운 것을 모두 사용하여 회원가입 기능을 만드는 것이다!
    후후.. 보기만 해도 근질근질하구만 바로 만들어보자고!
    우선 html!
<!DOCTYPE html>
<html lang="ko">
<head>
    <title>회원가입</title>
    <link rel="stylesheet" href="./final.css">
    <script src="./final.js"></script>
</head>
<body>
    <div class="wrapper">
        <div class="title">코드캠프 회원가입</div>
        <div class="info">
            <input id="email" type="text" placeholder="이메일을 입력해 주세요.">
            <div class="errorMessage" id="emailErrorMessage"></div>
        </div>
        <div class="info">
            <input id="name" type="text" placeholder="이름을 입력해 주세요.">
            <div class="errorMessage" id="nameErrorMessage"></div>
        </div>
        <div class="info">
            <input id="pw1" type="text" placeholder="비밀번호를 입력해 주세요.">
            <div class="errorMessage" id="pw1ErrorMessage"></div>
        </div>
        <div class="info">
            <input id="pw2" type="text" placeholder="비밀번호를 다시 입력해 주세요.">
            <div class="errorMessage" id="pw2ErrorMessage"></div>
        </div>
        <div class="phone__wrapper">
            <div class="phoneNumDiv">
                <input id="pNum1" type="text" maxlength="3" oninput="changeFocus1()">-
                <input id="pNum2" type="text" maxlength="4" oninput="changeFocus2()">-
                <input id="pNum3" type="text" maxlength="4" oninput="changeFocus3()">
            </div>
            <div class="tokenSendDiv">
                <div class="tokenText" id="tokenNum">000000</div>
                <button class="tokenBtn" id="tokenSend" onclick="tokenSend()" disabled="true">인증번호 전송</button>
            </div>
            <div class="tokenSubMitDiv">
                <div class="tokenText" id="tokenTimer">3:00</div>
                <button class="tokenBtn" id="tokenSubmit" onclick="tokenSubmit()"  disabled="true">인증확인</button>
            </div>
        </div>
        <div class="locationDiv">
            <select id="location">
                <option disabled="true" selected="true">지역을 선택하세요.</option>
                <option>인천</option>
                <option>서울</option>
                <option>경기</option>
            </select>
            <div class="errorMessage" id="locationErrorMessage"></div>
        </div>
        <div class="genderDiv">
            <div class="gender">
                <input type="radio" name="gender" value="W" id="gender1">여성
                <input type="radio" name="gender" value="M" id="gender2">남성
            </div>
            <div class="errorMessage" id="genderErrorMessage"></div>
        </div>
        <div class="divideLine"></div>
        <button class="submit" id="submit" onclick="submit()" disabled="true">가입하기</button>
    </div>
</body>
</html>

큰 구조를 먼저 잡고 차근차근 만들어나가니 헷갈리긴 했지만 어렵진 않았다!

다음 css!

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

html,
body {
    width: 1920px;
    height: 1196px;
}

body {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

.wrapper {
    width: 540px;
    height: 960px;
    background-color: #ffffff;
    border: 1px solid #AACDFF;
    box-shadow: 7px 7px 39px rgba(0, 104, 255, 0.25);
    border-radius: 20px;
    display: flex;
    flex-direction: column;
    justify-content: space-evenly;
    align-items: center;
}

.title {
    width: 380px;
    text-align: left;
    font-family: 'Noto Sans CJK KR';
    font-style: normal;
    font-weight: 700;
    font-size: 32px;
    line-height: 47px;
    margin : 10px 0px;
    color: #0068FF;
}

.info>input {
    width: 380px;
    height: 60px;
    background: #FFFFFF;
    border: 1px solid #D2D2D2;
    border-radius: 7px;
}

.errorMessage {
    width: 380px;
    text-align: center;
    font-size: 7px;
    color: red;
}

.phone__wrapper {
    width: 380px;
    display: flex;
    flex-direction: column;
}

.phoneNumDiv {
    width: 380px;
    /* font-size: 11px; */
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
}

.phoneNumDiv>input {
    width: 100px;
    height: 40px;
    background: #FFFFFF;
    border: 1px solid #D2D2D2;
    border-radius: 7px;
}

.tokenSendDiv {
    margin-top: 15px;
    width: 380px;
    display: flex;
    flex-direction: row;
    justify-content: flex-end;
    align-items: center;
}

.tokenSubMitDiv {
    margin-top: 15px;
    width: 380px;
    display: flex;
    flex-direction: row;
    justify-content: flex-end;
    align-items: center;
}

.tokenText {
    font-style: normal;
    font-weight: 400;
    font-size: 18px;
    line-height: 27px;
    color: #0068FF;
}

.tokenBtn {
    width: 120px;
    height: 40px;
    border-radius: 7px;
    border: 1px solid #D2D2D2;
    margin-left: 15px;
    font-family: 'Noto Sans CJK KR';
    font-style: normal;
    font-weight: 400;
    font-size: 16px;
    line-height: 24px;
    text-align: center;
}

#location {
    width: 380px;
    height: 60px;
    background: #FFFFFF;
    border: 1px solid #D2D2D2;
    border-radius: 7px;
}

.genderDiv {
    width: 380px;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.gender {
    display: flex;
    flex-direction: row;
    justify-content: center;     
}

.gender>input {
    margin: 3px;
}

#gender2 {
    margin-left: 15px;
}

.divideLine {
    border-top: 1px solid #E6E6E6;
    width: 380px;
}

.submit {
    width: 380px;
    height: 75px;
    border-radius: 10px;
    border: 1px solid #D2D2D2;
}

input , select {
    padding: 10px;
}

정렬의 고수가 된 기분이랄까? 조금 헤매긴 했다 ㅎㅎ..

다음 js!

// 핸드폰 번호 포커싱 옮기기
const changeFocus1 = () => {

    let pNum1 = document.getElementById("pNum1").value
    if (pNum1.length === 3) {
        document.getElementById("pNum2").focus()
    }
}

const changeFocus2 = () => {

    let pNum2 = document.getElementById("pNum2").value
    if (pNum2.length === 4) {
        document.getElementById("pNum3").focus()
    }
}

const changeFocus3 = () => {

    let pNum2 = document.getElementById("pNum3").value
    if (pNum2.length === 4) {
        document.getElementById("tokenSend").disabled = false
        document.getElementById("tokenSend").style = "background-color:#FFFFFF; border-color: #0068FF; color: #0068FF; cursor: pointer;"
    }
}

// 인증번호 전송 기능
let timer

const tokenSend = (arg) => {

    const token = String(Math.floor(Math.random() * 1000000)).padStart(6, "0")
    document.getElementById("tokenSend").disabled = true
    document.getElementById("tokenSend").style = ""
    document.getElementById("tokenNum").innerText = token

    let time = 180

    timer = setInterval(function () {

        if (time >= 0) {

            let min = Math.floor(time / 60)
            let sec = String(time % 60).padStart(2, "0")
            time = time - 1

            document.getElementById("tokenSubmit").disabled = false
            document.getElementById("tokenSubmit").style = "background-color:#0068FF; color: #FFFFFF; cursor: pointer;"
            document.getElementById("tokenTimer").innerText = min + ":" + sec
            

        } else {

            document.getElementById("tokenNum").innerText = "000000"
            document.getElementById("tokenTimer").innerText = "3:00"

            document.getElementById("tokenSubmit").disabled = true
            document.getElementById("tokenSubmit").style = ""

            document.getElementById("tokenSend").disabled = false
            document.getElementById("tokenSend").style = "background-color:#FFFFFF; border-color: #0068FF; color: #0068FF; cursor: pointer;"
            
            clearInterval(timer)

        }

    }, 1000)
}

// 인증완료 기능
const tokenSubmit = () => {

    let tokeTimer = document.getElementById("tokenTimer").innerText

    if (tokenTimer !== "0:00") {

        alert("인증이 완료되었습니다.")

        clearInterval(timer)

        document.getElementById("tokenNum").innerText = "000000"
        document.getElementById("tokenTimer").innerText = "3:00"

        document.getElementById("tokenSubmit").disabled = true
        document.getElementById("tokenSubmit").innerText = "인증완료"
        document.getElementById("tokenSubmit").style = ""

        document.getElementById("tokenSend").disabled = true

        document.getElementById("submit").disabled = false
        document.getElementById("submit").style = "background-color:#FFFFFF; border-color: #0068FF; color: #0068FF; cursor: pointer;"
    }
}

// 가입완료 기능
const submit = () => {

    let email = document.getElementById("email").value
    let name = document.getElementById("name").value
    let pw1 = document.getElementById("pw1").value
    let pw2 = document.getElementById("pw2").value
    let location = document.getElementById("location").value
    let gender = document.querySelector("input[name='gender']").checked

    let isValid = true

    if(!email.includes("@")) {
        document.getElementById("emailErrorMessage").innerText = "이메일이 올바르지 않습니다."
        isValid = false
    } else {
        document.getElementById("emailErrorMessage").innerText = ""  
    }

    if(name === "") {
        document.getElementById("nameErrorMessage").innerText = "이름이 올바르지 않습니다."
        isValid = false
    } else {
        document.getElementById("nameErrorMessage").innerText = ""   
    }

    if(pw1 === "" || pw2 === "" || pw1 !== pw2) {
        document.getElementById("pw1ErrorMessage").innerText = "비밀번호를 입력해 주세요."
        document.getElementById("pw2ErrorMessage").innerText = "비밀번호를 입력해 주세요."
        isValid = false
    } else {
        document.getElementById("pw1ErrorMessage").innerText = ""   
        document.getElementById("pw2ErrorMessage").innerText = ""   
    }


    if(location === "지역을 선택하세요.") {
        document.getElementById("locationErrorMessage").innerText = "지역을 선택해주세요."
        isValid = false
    } else {
        document.getElementById("locationErrorMessage").innerText = ""   
     }

    if(!gender) {
        document.getElementById("genderErrorMessage").innerText = "성별을 선택해주세요."
        isValid = false
    } else {
        document.getElementById("genderErrorMessage").innerText = ""    
    }

    if(isValid) {
        alert("코드캠프 가입을 축하합니다.")
    }

}

지금 코드를 다시 보니 뭔가 지저분한 느낌이다 함수 하나에 여러 기능을 포함하고 있어서 지저분한 것 같다
기능별로 함수를 나눠서 호출하는 방식으로 더 세분화했어도 괜찮았을 것 같다.

5일차 느낀점

한 주의 마지막 과제인 만큼 시간이 좀 걸리긴 했지만 확실히 강의를 듣고 만들다 보니 아 여기서 이 때 배운 이걸 쓰면 되겠는지? 가 파파파팍 머리에 바로 떠올랐다 블로그로 매일매일 정리하는 것도 혼자만의 코드 리뷰 느낌이라 복습도 되고 좋은 것 같다 매일매일 빼먹지 말고 앞으로도 파이팅!!


🏷 6일차 수업목차

  1. css 기본과 적용
  2. 선택자 1, 폰트 기본스타일
  3. 박스모델, inline vs blocdk
  4. 실습 1
  5. 레이아웃, 선택자 2
  6. css 레이아웃의 흐름
  7. float 레이아웃
  8. flex 레이아웃
  9. 실습 2

📌 오늘의 내용

  • css란?
    단순한 문서 형태인 HTML을 페이지의 요소들이 어디에 위치해야 하는지 레이아웃 구조를 잡아주고, 요소 하나하나를 개성 있고 사용이 편리하도록 꾸며주는 역할을 한다!

    css 문법의 기본 구조는 위 사진과 같다!
    그렇다면 적용하는 방법을 알아보자

inline style

<!--태그에 직접 style 적용-->
<h1 style="color:blue"> 제목이에요~ </h1>

style 태그 사용하기

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>html 사이트
    </title>
    <style>
        h1 {
            color : blue;
        }
    </style>
</head>
<body>
    <h1> 제목이에요~ </h1>
</body>
</html>

위 두 가지 방법은 당장 사용하긴 편하지만 유지 보수에 불리하므로 css 파일을 따로 분리해 주어야 한다!

<!--link 태그는 head태그 안에 있어야 한다.-->
<link href="./style.css" rel="stylesheet"/>

  • css 선택자

사용되는 선택자를 알아 보자!

/*태그 선택자*/
div {
    background-color : red;
}
/*id 선택자*/
#id {
    property : property value;
}
/*class 선택자*/
.class {
    property : property value;
}

/* 자손 선택자 사용예시 - .box 안에 있는 #title을 선택한다. */
.box #title {
    color : red
}
/* 다중 선택자 사용예시 - .box 이면서 동시에 #title인 요소를 선택한다. */
.box#title {
    color : red
}
/* 전체 선택자 */
* {
   property : property value
}
/* 그룹 선택자를 이용해서 한번에 처리 */
h2, p, div {
	color : blue
}

.some-box:hover{ background-color: red; }		/* 마우스를 요소에 올렸을때 */
.container-boxs:first-child{ margin-left: 0; }	/* 첫번째 자식 선택자 */
.container-boxs:last-child{ margin-right: 0; }	/* 마지막 자식 선택자 */
.contentsBox:nth-child(3){ color: red; }		/* 입력한 자식 선택자 */
  • 폰트 관련 스타일
.title {
	font-size : 15px; 			/* 글자 크기 조절 */
    font-weight : bold; 		/* 글자 굵기 조절 */
    font-style : italic; 		/* 글자 모양 조절 */
    text-decoration: underline; /* 글자 모양 조절 */
    color : red; 				/* 글자 색상 지정 */
}
  • box-sizing

    사실 잘 알지 못하고 사용하다가 강의를 듣고 알게 된 내용이다
    기본 속성은 content-box로 되어있지만 레이아웃이 깨지지 않는 게 좋기 때문에 border-box로 설정 해놓는 것이 좋다!

  • css 레이아웃
    HTML의 요소들을 배치하는 것을 레이아웃이라고 부르며 이 시스템에는 역사가 있습니다

    float -> flex -> grid 순서로 등장하였으며 보편적으로 flex와 grid를 혼용하는 추세다!!
    그럼 왜 float를 요즘 잘 쓰지 않는지 float와 flex로 같은 화면을 만들어보자

<!DOCTYPE html>
<html lang="ko">
<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>나만의 일기장!!</title>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <header class="header">
        <div class="header-inner">
            <div class="logo">
                <h1>
                    <a href="#none">HAGD</a>
                </h1>
            </div>
            <div class="menu">
                <ul class="menu__ul">
                    <li>
                        <a href="#none">어제의 일기</a>
                    </li>
                    <li>
                        <a href="#none">오늘의 일기</a>
                    </li>
                    <li>
                        <a href="#none">내일의 일기</a>
                    </li>  
                  <!-- <div class="clearfix"></div> -->
                </ul>
            </div>
            <div class="user">
                <img src="./img/portrait.png" alt="유저 정보" width="32" height="32">
            </div>
          <!-- <div class="clearfix"></div> -->
        </div>
    </header>
    <div class="container">
        <div class="wrapper">
            <div class="wrapper__head">
                <h1 class="wrapper__head__title">
                    나만의 일기장
                </h1>
                <p class="wrapper__head_sub-title">
                    나만의 일기장입니다!<br>
                    원하는 색과 사이즈로 일기장을 커스텀해보세요.
                    <span id="point">
                        Have a Good Day.😄
                    </span>
                </p>
            </div>
            <div class="wrapper__body">
                <div class="wrapper__body_content">
                    <p class="diary-title">
                        📌 쭈꾸미의 일기
                    </p>
                    <p>
                        오늘은 <span class="kimchi">김치찜을</span> 먹었다. <span class="egg">계란말이</span> 도 함께 있는 세트였다.<br>
                        맛있어서 정신없이 먹다 보니 배가 너무 불러서 힘들었다.<br>
                        내일은 <span class="highlight">과식하지 말아야겠다!!</span> 
                    </p>
                    <p class="diary-date">
                        2022년 7월 5일<br>
                        날씨 흐림 😭
                    </p>
                </div>
            </div>
        </div>
    </div>
</body>
</html>
/* float 사용*/
.header {
    border-bottom: 1px solid gray;
}

.header-inner {
    width: 900px;
    height: 100%;
    margin: 0 auto;
}

.logo h1 a {
    text-decoration: none;
    color: orange;
}

.logo {
    float: left;
    width: 100px;
    height: 80px;
    padding-top: 22px;
}

.menu {
    float: left;
    width: calc(100% - 200px);
    height: 80px;
    text-align: center;
}

.menu__ul {
   display: inline-block;
}

.menu__ul li {
    float: left;
    list-style: none;
}

.menu__ul li a {
    display: block;
    color: black;
    text-decoration: none;
    padding: 29px 20px;

}

.menu__ul li a:hover {
    color: orange;
}

.user {
    float: left;
    width: 100px;
    height: 80px;
    padding-top: 23px;
}

.clearfix {
    clear: both;
}
/* flex 사용 */
.header {
    height: 80px;
    display: flex;
    justify-content: center;
    align-items: center;
    border-bottom: 1px solid gray;
}

.header-inner {
    width: 900px;
    height: 100%;
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;
}

.logo {
    width: 100px;
}

.logo h1 a {
    text-decoration: none;
    color: orange;
}

.menu__ul {
    display: flex;
    flex-direction: row;
}

.menu__ul li {
    list-style: none;
}

.menu__ul li a {
    display: block;
    padding: 10px 20px;
    text-decoration: none;
    color: #000;
}

.user {
    width: 100px;
}

거의 같은 html 구조에서 float는 더 많은 양의 코드를 요구하고 사용하기에도 편리하지 않다
하지만 flex는 더 간결하며 사용하기도 편리하기 때문에 요즘에는 float 구조는 잘 쓰지 않는다.


하루를 마치며 :)

요번 주는 지난주에 배웠던 css에 대해 더 자세히 알아보는 시간이었다 세세하게 수업을 듣다 보니 확실히 이해하기 편했고 한번 배운 뒤 복습하는 느낌이라 더 쉽게 느껴지기도 했다.
아! 그리고 블로그 빼먹지 말자.. 2를 치는 양이 너무 많다

profile
같이 일하고 싶은 사람이 되어보자! 다시 시작하는 개발 블로그.

0개의 댓글