멋사 두 번째 과제

olhsg·2023년 3월 27일
0

멋쟁이 사자처럼

목록 보기
2/15

이번 과제는 동아리 활동 때 했던 네이버 회원가입 창 클론코딩에 이어서
html과 js 파일을 연결하는 것이다!
(그리고 활동 때 홀로 오류난 것을 고치는 것도...)




최종적인 결과물은~~~

이러하다!

클론 코딩이 처음이라서 흥미로운 시간이었다
괜히 내가 네이버 회사에 다니고 있는 것만 같은... 기분이랄까 (ㅋ)
무튼 이번 시간에 작성한 코딩은~

1.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>네이버 : 회원가입</title>
    <link rel="stylesheet" href="join.css">
</head>

<body>
   
    <div id="header">
        <a href="https://nid.naver.com/user2/V2Join.nhn?m=agree#agreeBottom" target="_blank" title="네이버 회원가입 페이지 바로가기">
            <img id="logo" src="NAVER_CI_Green.png">
        </a>
    </div>

    <div id="rapper">
        <div id="content">

            <!-- id -->
            <div>
                <h3 class="join_title">
                    <label for="id">아이디</label>
                </h3>
                <span class="box info_id">
                    <input type="text" id="id" class="info" maxlength="20">
                    <span class="auto_url">@naver.com</span>
                </span>
                <span class="error_next_box"></span>
            </div>

            <!-- pw -->
            <div>
                <h3 class="join_title">
                    <label for="pw1">비밀번호</label>
                </h3>
                <span class="box info_pw">
                    <input type="password" id="pw1" class="info" maxlength="20">
                    <img src="m_icon_pass.png" id="pw1_img1" class="pwImg">
                </span>
                <span class="error_next_box"></span>
            </div>

            <!-- pw_check -->
            <div>
                <h3 class="join_title">
                    <label for="pw2">비밀번호 재확인</label>
                </h3>
                <span class="box info_pw_check">
                    <input type="password" id="pw2" class="info" maxlength="20">
                    <img src="m_icon_check_disable.png" id="pw2_img1" class="pwImg">
                </span>
                <span class="error_next_box"></span>
            </div>

            <!-- name -->
            <div>
                <h3 class="join_title">
                    <label for="name">이름</label>
                </h3>
                <span class="box info_name">
                    <input type="text" id="name" class="info" maxlength="20">
                </span>
                <span class="error_next_box"></span>
            </div>

            <!-- birth yy -->
            <div>
                <h3 class="join_title">
                    <label for="yy">생년월일</label>
                </h3>
                <div id="bir_wrap">
                    <div id="bir_yy">
                        <span class="box">
                            <input type="text" id="yy" class="info" maxlength="4" placeholder="년(4자)">
                        </span>
                    </div>

                    <!-- dirth mm -->
                    <div id="bir_mm">
                        <span class="box">
                            <select id="mm" class="set">
                                <option></option>
                                <option value="01">1</option>
                                <option value="02">2</option>
                                <option value="03">3</option>
                                <option value="04">4</option>
                                <option value="05">5</option>
                                <option value="06">6</option>
                                <option value="07">7</option>
                                <option value="08">8</option>
                                <option value="09">9</option>
                                <option value="10">10</option>
                                <option value="11">11</option>
                                <option value="12">12</option>
                            </select>
                        </span>
                    </div>

                    <!-- dirth day -->
                    <div id="bir_dd">
                        <span class="box">
                            <input type="text" id="dd" class="info" maxlength="2" placeholder="">
                        </span>
                    </div>
                </div>
            </div>

            <!-- gender -->
            <div>
                <h3 class="join_title">
                    <label for="gender">성별</label>
                </h3>
                <span class="box info_gender">
                    <select id="gender" class="set">
                        <option>성별</option>
                        <option value="F">여자</option>
                        <option value="M">남자</option>
                        <option value="U">선택 안함</option>
                    </select>
                </span>
            </div>

            <!-- phone-number -->
            <div>
                <h3 class="join_title">
                    <label for="mobile">휴대전화</label>
                </h3>
                <span class="box info_mobile">
                    <input type="text" id="mobile" class="info" maxlength="18" placeholder="전화번호 입력">
                </span>
                <span class="error_next_box"></span>
            </div>

            <!-- join-button -->
            <div class="btn_area">
                <button type="button" id="button">
                    <span>가입하기</span>
                </button>
            </div>
        </div>
    </div>
    <script type="text/javascript" src="join.js"></script>
</body>

</html>

2. css

html {
    height: 100%;
}

body {
    margin: 0;
    height: 100%;
    background: #f3f6f7;
    font-family: Dotum, '돋움', Arial, Helvetica, sans-serif;
}

#logo {
    width: 240px;
    height: 44px;
}

#header {
    padding-top: 60px;
    padding-bottom: 20px;
    text-align: center;
}

#rapper {
    position: relative;
    height: 100%;
}

#content {
    position: absolute;
    left: 50%;
    transform: translate(-50%);
    width: 460px;
}

label {
    cursor: pointer;
}

input:focus {
    outline: none;
}

h3 {
    margin: 19px 0 8px;
    font-size: 14px;
    font-weight: 700;
}

.box {
    display: block;
    width: 100%;
    height: 51px;
    border: solid 1px #dadada;
    padding: 10px 14px 10px 14px;
    background: #ffffff;
    box-sizing: border-box;
    /* 테두리 포함 */
    position: relative;
}

.info {
    display: block;
    position: relative;
    width: 100%;
    height: 29px;
    border: none;
    background-color: #ffffff;
    font-size: 15px;
}

input {
    font-family: Dotum, '돋움', Helvetica, sans-serif;
}

.box.info_id {
    padding-right: 110px;
}

.box.info_pw {
    padding-right: 40px;
}

.box.info_pw_check {
    padding-right: 40px;
}

.auto_url {
    position: absolute;
    top: 16px;
    right: 13px;
    font-size: 15px;
    color: #8e8e8e;
}

.pwImg {
    width: 18px;
    height: 20px;
    display: inline;
    position: absolute;
    top: 50%;
    right: 16px;
    margin-top: -10px;
    cursor: pointer;
}

#bir_wrap {
    display: table;
    width: 100%;
}

#bir_yy {
    display: table-cell;
    width: 147px;
}

#bir_mm {
    display: table-cell;
    width: 147px;
    vertical-align: middle;
}

#bir_dd {
    display: table-cell;
    width: 147px;
}

#bir_mm,
#bir_dd {
    padding-left: 10px;
}

.set {
    width: 100%;
    height: 29px;
    font-size: 15px;
    line-height: 18px;
    color: #000;
    background: #ffffff url("sel_arr_2x.gif") 100% 50% no-repeat;
    -webkit-appearance: none;
    display: inline;
    text-align: start;
    border: none;
    cursor: default;
    font-family: Dotum, '돋움', Helvetica, sans-serif;
}

.error_next_box {
    margin-top: 9px;
    font-size: 9px;
    color: red;
}

.btn_area {
    margin: 3px 0 9px;
}


#button {
    display: block;
    width: 100%;
    padding: 15px 0 15px;
    border: solid 1px rgba(0, 0, 0, .08);
    cursor: pointer;
    background-color: #03c75a;
    font-size: 18px;
    text-align: center;
    font-weight: 700;
    box-sizing: border-box;
    font-family: Dotum, '돋움', Helvetica, sans-serif;
    color: #fff;
}

3. js (내가 직접 친 코딩은 아니고 연결한 파일이라 생각하면 된다)

var id = document.querySelector('#id');

var pw1 = document.querySelector('#pw1');
var pwMsg = document.querySelector('#alertTxt');
var pwImg1 = document.querySelector('#pw1_img1');

var pw2 = document.querySelector('#pw2');
var pwImg2 = document.querySelector('#pw2_img1');
var pwMsgArea = document.querySelector('.state_pass');

var userName = document.querySelector('#name');

var yy = document.querySelector('#yy');
var mm = document.querySelector('#mm');
var dd = document.querySelector('#dd');

var gender = document.querySelector('#gender');

var email = document.querySelector('#email');

var mobile = document.querySelector('#mobile');

var error = document.querySelectorAll('.error_next_box');



/*이벤트 핸들러 연결*/


id.addEventListener("focusout", checkId);
pw1.addEventListener("focusout", checkPw);
pw2.addEventListener("focusout", comparePw);
userName.addEventListener("focusout", checkName);
yy.addEventListener("focusout", isBirthCompleted);
mm.addEventListener("focusout", isBirthCompleted);
dd.addEventListener("focusout", isBirthCompleted);
gender.addEventListener("focusout", function() {
    if(gender.value === "성별") {
        error[5].style.display = "block";
    } else {
        error[5].style.display = "none";
    }
})
email.addEventListener("focusout", isEmailCorrect);
mobile.addEventListener("focusout", checkPhoneNum);





/*콜백 함수*/


function checkId() {
    var idPattern = /[a-zA-Z0-9_-]{5,20}/;
    if(id.value === "") {
        error[0].innerHTML = "필수 정보입니다.";
        error[0].style.display = "block";
    } else if(!idPattern.test(id.value)) {
        error[0].innerHTML = "5~20자의 영문 소문자, 숫자와 특수기호(_),(-)만 사용 가능합니다.";
        error[0].style.display = "block";
    } else {
        error[0].innerHTML = "멋진 아이디네요!";
        error[0].style.color = "#08A600";
        error[0].style.display = "block";
    }
}

function checkPw() {
    var pwPattern = /[a-zA-Z0-9~!@#$%^&*()_+|<>?:{}]{8,16}/;
    if(pw1.value === "") {
        error[1].innerHTML = "필수 정보입니다.";
        error[1].style.display = "block";
    } else if(!pwPattern.test(pw1.value)) {
        error[1].innerHTML = "8~16자 영문 대 소문자, 숫자, 특수문자를 사용하세요.";
        pwMsg.innerHTML = "사용불가";
        pwMsgArea.style.paddingRight = "93px";
        error[1].style.display = "block";
        
        pwMsg.style.display = "block";
        pwImg1.src = "m_icon_not_use.png";
    } else {
        error[1].style.display = "none";
        pwMsg.innerHTML = "안전";
        pwMsg.style.display = "block";
        pwMsg.style.color = "#03c75a";
        pwImg1.src = "m_icon_safe.png";
    }
}

function comparePw() {
    if(pw2.value === pw1.value && pw2.value != "") {
        pwImg2.src = "m_icon_check_enable.png";
        error[2].style.display = "none";
    } else if(pw2.value !== pw1.value) {
        pwImg2.src = "m_icon_check_disable.png";
        error[2].innerHTML = "비밀번호가 일치하지 않습니다.";
        error[2].style.display = "block";
    } 

    if(pw2.value === "") {
        error[2].innerHTML = "필수 정보입니다.";
        error[2].style.display = "block";
    }
}

function checkName() {
    var namePattern = /[a-zA-Z가-힣]/;
    if(userName.value === "") {
        error[3].innerHTML = "필수 정보입니다.";
        error[3].style.display = "block";
    } else if(!namePattern.test(userName.value) || userName.value.indexOf(" ") > -1) {
        error[3].innerHTML = "한글과 영문 대 소문자를 사용하세요. (특수기호, 공백 사용 불가)";
        error[3].style.display = "block";
    } else {
        error[3].style.display = "none";
    }
}


function isBirthCompleted() {
    var yearPattern = /[0-9]{4}/;

    if(!yearPattern.test(yy.value)) {
        error[4].innerHTML = "태어난 년도 4자리를 정확하게 입력하세요.";
        error[4].style.display = "block";
    } else {
        isMonthSelected();
    }


    function isMonthSelected() {
        if(mm.value === "월") {
            error[4].innerHTML = "태어난 월을 선택하세요.";
        } else {
            isDateCompleted();
        }
    }

    function isDateCompleted() {
        if(dd.value === "") {
            error[4].innerHTML = "태어난 일(날짜) 2자리를 정확하게 입력하세요.";
        } else {
            isBirthRight();
        }
    }
}



function isBirthRight() {
    var datePattern = /\d{1,2}/;
    if(!datePattern.test(dd.value) || Number(dd.value)<1 || Number(dd.value)>31) {
        error[4].innerHTML = "생년월일을 다시 확인해주세요.";
    } else {
        checkAge();
    }
}

function checkAge() {
    if(Number(yy.value) < 1920) {
        error[4].innerHTML = "정말이세요?";
        error[4].style.display = "block";
    } else if(Number(yy.value) > 2024) {
        error[4].innerHTML = "미래에서 오셨군요. ^^";
        error[4].style.display = "block";
    } else if(Number(yy.value) > 2008) {
        error[4].innerHTML = "만 14세 미만의 어린이는 보호자 동의가 필요합니다.";
        error[4].style.display = "block";
    } else {
        error[4].style.display = "none";
    }
}


function isEmailCorrect() {
    var emailPattern = /[a-z0-9]{2,}@[a-z0-9-]{2,}\.[a-z0-9]{2,}/;

    if(email.value === ""){ 
        error[6].style.display = "none"; 
    } else if(!emailPattern.test(email.value)) {
        error[6].style.display = "block";
    } else {
        error[6].style.display = "none"; 
    }

}

function checkPhoneNum() {
    var isPhoneNum = /([01]{2})([01679]{1})([0-9]{3,4})([0-9]{4})/;

    if(mobile.value === "") {
        error[7].innerHTML = "필수 정보입니다.";
        error[7].style.display = "block";
    } else if(!isPhoneNum.test(mobile.value)) {
        error[7].innerHTML = "형식에 맞지 않는 번호입니다.";
        error[7].style.display = "block";
    } else {
        error[7].style.display = "none";
    }

    
}


그렇다 꽤 길다... (내 기준)
첫 번째 과제에 이어서 html의 구조를 좀 더 익히기 위한? 심화 작업이라 생각하면 될 것 같은데 첫 번째 과제는 기본적인 태그들이 어떠한 것인지를 보기 위해 시험적으로 결과물을 만들었다면 두 번째 과제에서는 확고한 결과물이 있어서 좋았다!

4.html에 js 파일 연결하는 방법

생각보다 간단하다!
body 태그 안에 script 태그를 추가하여 js파일을 연결하면 된다!

 <script type="text/javascript" src="join.js"></script>

이미지 추가할 때를 생각하면 된다!
이때 body 태그 맨 아래에 적어주는 게 좋다고 한다.
그러한 이유는 컴파일 처리 순서때문이다.

5. 나의 오류...

마지막으로 나의 오류에 대해 설명을 하자면
동아리 활동했을 때 css까지 모든 작성을 마친 뒤 아이디, 비밀번호, 비밀번호 재확인, 이름, 생년월일까지의 체크 박스는 제대로 잘 나왔는데...
성별, 휴대전화의 체크박스가 css에서 설정한 값처럼 안 나오는 거였다 ㅠㅠ

html 안에서 div 태그의 위치들도 잘 맞았고, <>도 빠짐없이 작성했는데
왜 오류가 날까? 생각하다 발견한 오류는...
html 에서의 클래스명과 css의 클래스명이 일치하지 않아서였다...!
진짜 혹시나...? 하고 확인했는데

<span class="box_info_mobile">

.box{
    display: block;
    width: 100%;
    height: 51px;
    border: solid 1px #dadada;
    padding: 10px 14px 10px 14px;
    background: #ffffff;
    box-sizing: border-box; /* 테두리 포함 */
    position: relative;
}

당시 내가 html에 쓴 클래스 명은 'box_info_mobile' 인데
css에 쓴 명은 .box인 것...
그렇다 'box info_mobile'이라 작성해야 .box의 속성을 따로 지정할 수 있는 것인데 중간에 내가 홀로 언더바를 작성하는 바람에 속성 적용이 안 되고 있던 거다 ㅋㅋ...
(동아리 활동 중 혼자 코드를 작성해보겠다고 혼자 클래스 명을 다르게 써서...)
클래스 명을 box info_mobile로 변경하니 아주 깔끔하게 css가 적용된 창을 볼 수 있었다 ^^

6. 마지막으로 오늘의 교훈

오류는 생각보다 기본적인 곳에서 많이 나니
오타, 클래스 명의 일치, 태그가 잘 닫혔는지, 태그의 정렬이 잘 됐는지를 먼저 확인하자!!!

profile
누구보다 밝게 코딩하기♡

0개의 댓글