본문 바로가기

Java 웹 개발

21.11.09 - 웹 개발 입문 62일차

자바스크립트

 

Q. 과제풀이

회원 가입 화면을 만들고 규칙에 맞게 입력값을 검사하여 출력

<!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>Document</title>
    <link rel="stylesheet" type="text/css" href="./css/commons.css">
    <style>
        div {
            border:0px dotted black;
        }
        .notice {
            color:red;
        }
    </style>
    <script>

        function idCheck(){
            var regex = /^[a-z][a-z0-9-_]{7,19}$/;
            var input = document.querySelector("input[name=memberId]");
            //var notice = document.querySelector("input[name=memberId] + .notice");
            var notice = input.nextElementSibling;

            if(regex.test(input.value)){
                notice.textContent = "";
                return true;
            }
            else{
                notice.textContent = "아이디는 8~20자 영문+숫자로 작성하세요";
                return false;
            }
        }

        function pwCheck(){
            var regex = /^[A-Za-z0-9!@#$\s_-]{8,16}$/;
            var input = document.querySelector("input[name=memberPw]");
            //var notice = document.querySelector("input[name=memberPw] + .notice");
            var notice = input.nextElementSibling;

            if(regex.test(input.value)){
                notice.textContent = "";
                return true;
            }
            else{
                notice.textContent = "비밀번호는 8~16자 이내의 영문,숫자,특수문자로 작성하세요";
                return false;
            }
        }
        function pw2Check(){
            //비밀번호 확인은 비밀번호 입력창 2개가 필요하다.
            var pwInput = document.querySelector("input[name=memberPw]");
            var pw2Input = document.querySelector("input[name=memberPw2]");
            var notice = pw2Input.nextElementSibling;
            //비밀번호 일치 = 입력창이 비어있지 않고 두 비밀번호 입력값이 같은 경우
            if(pwInput.value.length > 0 && pwInput.value == pw2Input.value){
                notice.textContent = "";
                return true;
            }
            else{
                notice.textContent = "비밀번호가 일치하지 않습니다";
                return false;
            }
        }
        function nicknameCheck(){
            var regex = /^[가-힣0-9]{2,10}$/;
            var input = document.querySelector("input[name=memberNick]");
            //var notice = document.querySelector("input[name=memberNick] + .notice");
            var notice = input.nextElementSibling;

            if(regex.test(input.value)){
                notice.textContent = "";
                return true;
            }
            else{
                notice.textContent = "닉네임은 한글, 숫자 2~10자로 작성하세요";
                return false;
            }
        }
        function birthCheck(){
            //입력이 되어있는지만 확인
            var input = document.querySelector("input[name=memberBirth]");
            var notice = input.nextElementSibling;

            if(input.value.length > 0){
                notice.textContent = "";
                return true;
            }
            else{
                notice.textContent = "생년월일을 선택하세요";
                return false;
            }
        }
        function emailCheck(){
            var regex = /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$/;
            var input = document.querySelector("input[name=memberEmail]");
            //var notice = document.querySelector("input[name=memberEmail] + .notice");
            var notice = input.nextElementSibling;

            if(input.value.length == 0 || regex.test(input.value)){
                notice.textContent = "";
                return true;
            }
            else{
                notice.textContent = "이메일 형식이 올바르지 않습니다";
                return false;
            }
        }
        function phoneCheck(){
            var regex = /^01[016789][1-9][0-9]{3}[0-9]{4}$/;
            var input = document.querySelector("input[name=memberPhone]");
            //var notice = document.querySelector("input[name=memberPhone] + .notice");
            var notice = input.nextElementSibling;

            if(input.value.length == 0 || regex.test(input.value)){
                notice.textContent = "";
                return true;
            }
            else{
                notice.textContent = "전화번호는 - 없이 11자리로 작성하세요";
                return false;
            }
        }

        function formCheck(){
            return idCheck() && pwCheck() && pw2Check() && nicknameCheck() && birthCheck() 
                            && emailCheck() && phoneCheck();
        }
    </script>
</head>
<body>
    <form action="" method="post" enctype="multipart/form-data" onsubmit="return formCheck();">
        <div class="container-600 container-center">
            <div class="row center">
                <h1>회원 가입</h1>
            </div>
            <div class="row">
                <label>아이디</label>
                <input type="text" name="memberId" class="form-input" onblur="idCheck();">
                <div class="notice"></div>
            </div>
            <div class="row">
                <label>비밀번호</label>
                <input type="password" name="memberPw" class="form-input" onblur="pwCheck();">
                <div class="notice"></div>
            </div>
            <div class="row">
                <label>비밀번호 확인</label>
                <input type="password" name="memberPw2" class="form-input" onblur="pw2Check();">
                <div class="notice"></div>
            </div>
            <div class="row">
                <label>닉네임</label>
                <input type="text" name="memberNick" class="form-input" onblur="nicknameCheck();">
                <div class="notice"></div>
            </div>
            <div class="row">
                <label>생년월일</label>
                <input type="date" name="memberBirth" class="form-input" onblur="birthCheck();">
                <div class="notice"></div>
            </div>
            <div class="row">
                <label>이메일</label>
                <input type="email" name="memberEmail" class="form-input" onblur="emailCheck();">
                <div class="notice"></div>
            </div>
            <div class="row">
                <label>전화번호</label>
                <input type="tel" name="memberPhone" class="form-input" onblur="phoneCheck();">
                <div class="notice"></div>
            </div>
            <div class="row">
                <input type="submit" value="회원가입" class="form-btn">
            </div>
        </div>        
    </form>
</body>
</html>

 

 

 

 

기본 이벤트 처리

기본 이벤트가 설정된 태그 : <a>, <form>
= 이 태그들은 기본적으로 설정된 동작이 존재한다.
= 이벤트를 추가하려면 반드시 기본 동작을 제한해야 한다.
= 이러한 태그들은 이벤트 설정 코드에 return false라고 적으면 기본동작을 하지 않는다.
= 내가 원하는 기능을 실행하고 기본 이벤트를 차단하려면 함수에서 반드시 true/false를 반환

<!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>
    <script>
        function notice(){
            //목표 : 정말 이동할것인지 확인하는 창을 띄워 확인을 누를 때만 이동
            //명령 : window.confirm() - 확인창 - 확인(true), 취소(false)를 반환
            var choice = window.confirm("정말 이동하시겠습니까?");
            // if(choice){
            //     return true;
            // }
            // else{
            //     return false;
            // }
            return choice;
        }
    </script>
</head>
<body>
    <a href="https://www.google.com" onclick="notice();">구글로 이동</a>
    <hr>
    <a href="https://www.google.com" onclick="return false;">구글로 이동</a>
    <hr>
    <a href="https://www.google.com" onclick="return true;">구글로 이동</a>
    <hr>
    <a href="https://www.google.com" onclick="return notice();">구글로 이동</a>
</body>
</html>

 


form 의 경우 submit 이벤트가 내장되어 있다.
= 따라서 상황에 맞게 이를 허용(return true)하거나 차단(return false) 처리를 할 수 있어야 한다
= 검사 함수를 만들고 필요한 검사를 수행한 뒤 합격하면 허용하는 방법으로 처리한다.

<!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>
    <script>
        function formCheck(){

            var keywordInput = document.querySelector("input[name=keyword]");
            if(keywordInput.value.length == 0){//입력이 안되어 있다면
                //원하는 코드 추가(메세지 출력, 알림창 출력, ...)
                window.alert("검색어를 작성하세요");
                keywordInput.focus();
                return false;
            }

            //return true;
        }
    </script>
</head>
<body>
    <form action="https://www.google.com" method="get" onsubmit="return formCheck();">
        <input type="text" name="keyword">
        <input type="submit" value="전송">
    </form>
</body>
</html>

 

 

기본 내장 객체

모든 언어에는 각자의 내장 객체가 존재하며, 주로 자주 사용하는 기능들을 처리하는 역할 수행
자바스크립트는 브라우저에 종속된 언어이기 때문에 브라우저를 제어하는 기능들이 필요하다.
- window : 브라우저 창을 의미하는 최상위 객체(window라는 단어를 쓰지 않아도 된다)

<!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>
    <script>
        function windowTest1(){
            //console.log(window);
            window.alert("알림창 테스트");
        }
        function windowTest2(){
            var choice = window.confirm("확인창 테스트");
            console.log(choice);
        }
        function windowTest3(){
            window.open("https://www.google.com");
        }
        function windowTest4(){
            window.open("https://www.google.com", "popup", "width=500 , height=500");
        }
        function windowTest5(){
            //지연 실행 : window.setTimeout(함수, 지연시간) - 지연시간 후 함수 실행
            window.setTimeout(function(){
                    window.alert("안녕!");
            }, 5000);
        }

        function locationTest1(){
            //console.log(window.location);
            //console.log(location);

            location.href = "https://www.google.com";
        }
        function locationTest2(){
            location.reload();
        }
        function historyTest1(){
                //history.go(1);
                history.forward();
        }
        function historyTest2(){
                //history.go(-1);
                history.back();
        }
        function documentTest1(){
            //태그를 선택하는 다양한 방법 (이름, 아이디, 클래스)
            //구버전 : 명령이 전부 다 다르다. 모든 브라우저에서 작동한다.
            //var tag = document.getElementById("hello");
            //var tag = document.getElementsByTagName("h1")[0];
            //var tag = document.getElementsByClassName("test")[0];

            //신버전 : css 선택자 사용 및 명령 통합. 일부 구버전 브라우저에서 작동하지 않는다.
            //var tag = document.querySelector("#hello");
            //var tag = document.querySelector("h1");
            var tag = document.querySelector(".test");

            tag.style.color = "red";

            //var tag2 = document.querySelector(".test2");
            //tag2.style.color = "blue";

            //신버전 : 모두 다 불러오는 명령(배열 결과)
            var list = document.querySelectorAll(".test2");
            console.log(list);

            for(var i=0; i < list.length; i++){
                list[i].style.color = "blue";
            }
       }
    </script>
</head>
<body>
    <button onclick="windowTest1();">알림창</button>
    <button onclick="windowTest2();">확인창</button>
    <button onclick="windowTest3();">새 탭</button>
    <button onclick="windowTest4();">새 창</button>
    <button onclick="windowTest5();">타임아웃</button>
    <hr>
    <button onclick="locationTest1();">페이지이동</button>
    <button onclick="locationTest2();">새로고침</button>
    <hr>
    <button onclick="historyTest1();">앞으로가기</button>
    <button onclick="historyTest2();">뒤로가기</button>
    <hr>
    <button onclick="documentTest1();">태그 선택</button>
    <h1 id="hello" class="test">Hello Javascript</h1>

    <h2 class="test2">다중 선택 샘플</h2>
    <h2 class="test2">다중 선택 샘플</h2>
    <h2 class="test2">다중 선택 샘플</h2>
    <h2 class="test2">다중 선택 샘플</h2>
    <h2 class="test2">다중 선택 샘플</h2>
</body>
</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>
    <script>
        function check(){
            var ck = document.querySelector("#ck-box");
            //ck.checked = "checked";
            ck.checked = true;
        }
        function uncheck(){
            var ck = document.querySelector("#ck-box");
            //ck.checked = "";
            ck.checked = false;
        }
    </script>
</head>
<body>
    <button onclick="check();">체크</button>
    <button onclick="uncheck();">해제</button>
    <hr>
    <input type="checkbox" id="ck-box">
</body>
</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>
    <style>
        label {
            display: block;
        }
    </style>
    <script>
        /*
            checkbox는 onclick, oninput, onchange 모두 가능하지만
            oninput이 가장 맞는 이벤트 형태
            (구버전에서는 onchange)
        */
        function checkToggle(){
            var checkbox = document.querySelector(".check-all");
            //console.log(checkbox.checked);

            var checkboxList = document.querySelectorAll("input[type=checkbox]:not(.check-all)");
            console.log(checkboxList);

            if(checkbox.checked == true){//전체선택이 체크되었다면
                //모든체크박스를 체크한다
                for(var i=0; i < checkboxList.length; i++){
                    checkboxList[i].checked = true;
                }
            }
            else{//전체선택이 체크해제되었다면
                //모든체크박스를 체크해제한다
                for(var i=0; i < checkboxList.length; i++){
                    checkboxList[i].checked = false;
                }
            }
        }

        //checkToggle 압축버전
        function checkToggle2(){
            var checkbox = document.querySelector(".check-all");
            var checkboxList = document.querySelectorAll("input[type=checkbox]:not(.check-all)");

            for(var i=0; i < checkboxList.length; i++){
                checkboxList[i].checked = checkbox.checked;
            }
        }

        function check(){
            var checkboxList = document.querySelectorAll("input[type=checkbox]:not(.check-all)");
            var count = 0;
            for(var i=0; i < checkboxList.length; i++){
                if(checkboxList[i].checked){//체크되었다면
                    count++;//카운트증가
                }
            }
            //전부다 체크되었으면 count == checkboxList.length

            var checkbox = document.querySelector(".check-all");
            checkbox.checked = (count == checkboxList.length);
        }

        function check2(){
            var checkboxList = document.querySelectorAll("input[type=checkbox]:not(.check-all)");
            var checkboxList2 = document.querySelectorAll("input[type=checkbox]:not(.check-all):checked");

            var checkbox = document.querySelector(".check-all");
            checkbox.checked = (checkboxList.length == checkboxList2.length);
        }
    </script>
</head>
<body>
    <label>
        <input type="checkbox" oninput="checkToggle2();" class="check-all"> 
        <span>전체 선택</span>
    </label>
    <hr>
    <label><input type="checkbox" oninput="check2();"><span>딸기</span></label>
    <label><input type="checkbox" oninput="check2();"><span>포도</span></label>
    <label><input type="checkbox" oninput="check2();"><span>람부탄</span></label>
    <label><input type="checkbox" oninput="check2();"><span>홍시</span></label>
    <label><input type="checkbox" oninput="check2();"><span>두리안</span></label>
    <label><input type="checkbox" oninput="check2();"><span>오렌지</span></label>
    <label><input type="checkbox" oninput="check2();"><span>망고</span></label>
    <label><input type="checkbox" oninput="check2();"><span>파인애플</span></label>
    <label><input type="checkbox" oninput="check2();"><span>용과</span></label>
    <label><input type="checkbox" oninput="check2();"><span>샤인머스켓</span></label>
    <label><input type="checkbox" oninput="check2();"><span>스타후르츠</span></label>
</body>
</html>

 

 

 

클래스 제어

목표 : 버튼들을 누르면 해당하는 클래스를 추가
클래스는 제어 명령이 다르다
- className 속성 사용 : 기존의 클래스까지 모두 덮어쓰기
= class라는 속성 대신 className으로 직접 class="" 부분을 작성할 수 있다.
- classList 속성 사용 
= 모든 태그 객체는 classList라는 클래스 저장소를 가진다.
= 명령이 다양해지며 기존 클래스와 충돌이 발생하지 않는다

<!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>
    <style>
        .danger {
            color:red;
        }
        .success {
            color:#00b894;
        }
    </style>
    <script>
        function success(){
            var h1 = document.querySelector(".title");
            //h1.className = "success";//덮어쓰기
            remove();
            h1.classList.add("success");//추가
        }
        function danger(){
            var h1 = document.querySelector(".title");
            //h1.className = "danger";//덮어쓰기
            remove();
            h1.classList.add("danger");//추가
        }
        function remove(){
            var h1 = document.querySelector(".title");
            //h1.className = "";//전체 삭제
            h1.classList.remove("success", "danger");//선택 삭제
        }
    </script>
</head>
<body>
    <button onclick="success();">success</button>
    <button onclick="danger();"">danger</button>
    <button onclick="remove();">remove</button>
    <h1 class="title">Javascript Class Control</h1>
</body>
</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" type="text/css" href="./css/commons.css">
    <style>
        .form-input {
            outline: none;
            background-repeat: no-repeat;
            background-size: contain;
            background-position: right;
        }
        .form-input.success {
            border-color: green;
            background-image: url("./image/success.jpg");
        }
        .form-input.fail {
            border-color: red;
            background-image: url("./image/fail.jpg");
        }
        span.success {
            color:green;
            display: none;
        }
        span.fail {
            color:red;
            display: none;
        }
        .form-input.success ~ span.success { 
            display:block;
        }
        .form-input.fail ~ span.fail {
            display: block;
        }
    </style>
    <script>
        function idCheck(){
            var idInput = document.querySelector("input[name=memberId]");
            var regex = /^[a-z][a-z0-9]{7,19}$/;

            idInput.classList.remove("success", "fail");
            if(regex.test(idInput.value)){//원하는 형식인 경우
                idInput.classList.add("success");
            }
            else{//원하는 형식이 아닌 경우
                idInput.classList.add("fail");
            }
        }        
    </script>
</head>
<body>
    <form>
        <div class="container-500 container-center">
            <div class="row">
                <label>아이디</label>
                <input type="text" name="memberId" class="form-input" autocomplete="off" oninput="idCheck();">
                <span class="success">멋진 아이디네요!</span>
                <span class="fail">아이디는 8~20자 이내 영문 소문자 + 숫자로 작성하세요!</span>
            </div>            
        </div>
    </form>
</body>
</html>