웹_프론트_백엔드/프론트엔드

2020.09.27

shine94 2020. 9. 29. 00:43

1. 자바스크립트 정규식(=정규 표현식)

   ^x : 문자열이 x로 시작한다.
   x$ : 문자열이 x로 끝난다.
   .x : 임의의 한 문자를 표현한다.
   x+ : x가 1번이상 반복한다.
   x? : x가 존재하거나 존재하지 않는다.
   x* : x가 0번이상 반복한다.
   x|y : x또는 y를 찾는다.
   (x), (x)(y), (x)(?:y) : ()안의 내용을 캡쳐하며, 그룹화 한다.
   x{n} : x를 n번 반복한 문자를 찾는다.
   x{n,} : x를 n번 이상 반복한 문자를 찾는다.
   x{n,m} : x를 n번 이상 m번 이하 반복한 문자를 찾는다.
   [xy] : x,y중 하나를 찾는다.
   [^xy] : x,y를 제외하고 문자 하나를 찾는다.
   [x-z] : x~z 사이의 문자중 하나를 찾는다.
   \^ : 특수문자를 문자로 인식한다.
   \b : 문자와 공색사이의 문자를 찾는다.
   \B : 문자와 공백사이가 아닌 값을 찾는다.
   \d : 숫자를 찾는다.
   \D : 숫자가 아닌 값을 찾는다.
   \s : 공백문자를 찾는다.
   \S : 공백이 아닌 문자를 찾는다.
   \t : Tab 문자를 찾는다.
   \v : Vertical Tab 문자를 찾는다.
   \w : 알파벳 + 숫자 + _ 를 찾는다.
   \W : 알파벳 + 숫자 + _을 제외한 모든 문자를 찾는다.

 

 

2. test() : 정규 표현식에 대입한 문자열이 부합하면 true, 아니면 false를 반환한다.
   [예] const 상수이름 = /정규식 패턴/;
         cosnt 문자열 = 값;

         상수이름.test(문자열);    // true or false



3. 다음 우편번호 API

   http://postcode.map.daum.net/guide

 


4. 회원가입

 : 정규 표현식과 다음 우편번호 API를 사용하여 만들어보자!

 

** 1_회원가입.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>회원가입</title>
    <script src="https://t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
    <script src="./JS/member.js"></script>
</head>
<body>
    <h2>회원가입</h2>
    <form name="regform" id="regform" method="post" action="regist_ok.php" onsubmit="return sendit()">
        <input type="hidden" name="isSsn" id="isSsn" value="false">
        <p><label>아이디 : <input type="text" name="userid" id="userid" maxlength="20"></label></p>
        <p><label>비밀번호 : <input type="password" name="userpw" id="userpw" maxlength="20"></label></p>
        <p><label>비밀번호 확인 : <input type="password" name="userpw_re" id="userpw_re" maxlength="20"></label></p>
        <p><label>이름 : <input type="text" name="username" id="username"></label></p>
        <p><label>휴대폰 번호 : <input type="text" name="hp" id="hp"></label> ('-' 을 포함)</p>
        <p><label>이메일 : <input type="text" name="email" id="email"></label></p>
        <p>취미 : 
            <label>드라이브<input type="checkbox" name="hobby" value="드라이브"></label>
            <label>등산<input type="checkbox" name="hobby" value="등산"></label>
            <label>영화감상<input type="checkbox" name="hobby" value="영화감상"></label>
            <label>게임<input type="checkbox" name="hobby" value="게임"></label>
        </p>
        <p>주민등록번호 : 
            <input type="text" name="ssn1" id="ssn1" maxlength="6" onkeyup="moveFocus()"> - <input type="password" name="ssn2" id="ssn2" maxlength="7">
            <input type="button" value="주민등록번호 검증" onclick="ssnCheck()">
        </p>
        <p>우편번호 : <input type="text" name="zipcode" id="sample6_postcode"> <input type="button" value="우편번호 검색" onclick="sample6_execDaumPostcode()"></p>
        <p><label>주소 : <input type="text" name="address1" id="sample6_address"></label></p>
        <p><label>상세주소 : <input type="text" name="address2" id="sample6_detailAddress"></label></p>
        <p><label>참고항목 : <input type="text" name="address3" id="sample6_extraAddress"></label></p>
        <p><input type="submit" value="가입완료"> <input type="reset" value="다시작성"></p>
    </form>
</body>
</html>


** JS > member.js

'use strict';
function sendit() {
    //console.log('sendit 호출');
    // 객체 저장
    const userid = document.getElementById('userid');
    const userpw = document.getElementById('userpw');
    const userpw_re = document.getElementById('userpw_re');
    const username = document.getElementById('username');
    const hp = document.getElementById('hp');
    const email = document.getElementById('email');
    const hobby = document.getElementsByName('hobby');
    const isSsn = document.getElementById('isSsn');

    // 정규식
    const expPwText = /^.*(?=^.{4,20}$)(?=.*\d)(?=.*[a-zA-Z])(?=.*[!@#$%^&*()+=]).*$/;
    const expNameText = /[가-힣]+$/;
    const expHpText = /^\d{3}-\d{3,4}-\d{4}$/;
    const expEmailText = /^[A-Za-z0-9\.\-]+@[A-Za-z0-9\.\-]+\.[A-Za-z0-9\.\-]+$/;

    // 사용자가 느끼기에 위에서부터 체크한다는 느낌을 주기 위해서는
    // 검사를 할 때도 순서를 잘 정해야 한다.
    if(userid.value == ''){
        alert('아이디를 입력하세요.');
        userid.focus();
        return false;   // 페이지 이동 X
    }
    if(userid.value.length < 4 || userid.value.length > 20){
        alert('아이디를 4자이상 20자 이하로 입력하세요.');
        userid.focus();
        return false;   // 페이지 이동 X
    }
    if(userpw.value == ''){
        alert('비밀번호를 입력하세요.');
        userpw.focus();
        return false;   // 페이지 이동 X
    }
    if(expPwText.test(userpw.value) == false){
        alert('비밀번호 형식을 확인하세요.');
        userpw.focus();
        return false;   // 페이지 이동 X
    }
    if(userpw.value != userpw_re.value){
        alert('비밀번호와 비밀번호 확인의 값이 서로 다릅니다.');
        userpw.focus();
        return false;   // 페이지 이동 X
    }
    
    // 입력 값이 없으면 어차피 정규식에서 체크가 되기 때문에
    // 여기서부터는 값을 입력했는지 확인하는 작업 생략
    if(expNameText.test(username.value) == false){
        alert('이름 형식을 확인하세요.');
        username.focus();
        return false;   // 페이지 이동 X
    }
    if(expHpText.test(hp.value) == false){
        alert('휴대폰 번호 형식을 확인하세요.');
        hp.focus();
        return false;   // 페이지 이동 X
    }
    if(expEmailText.test(email.value) == false){
        alert('이메일 형식을 확인하세요.');
        email.focus();
        return false;   // 페이지 이동 X
    }

    // id는 하나만 설정할 수 있기 때문에
    // 취미라는 체크박스을 id로 여러 개 설정할 수 없다.
    // 그리고 getElementById 자체도 하나 밖에 값을 못가져오니
    // 취미라는 체크박스를 name을 통해 여러 개 설정 가능하고 
    // 체크박스의 값을 선택했는지 검사도 가능하다.
    let cnt = 0;
    for(let i=0; i<hobby.length; i++){
        if(hobby[i].checked){
            cnt++;
        }
    }
    if(cnt == 0){
        alert('취미는 적어도 1개이상 선택하세요.');
        return false;   // 페이지 이동 X
    }

    if(isSsn.value == 'false'){
        alert('주민등록번호 검증을 확인하세요.');
        ssn1.focus();
        return false;   // 페이지 이동 X
    }

    return true;        // 페이지 이동 O
}

function moveFocus(){
    const ssn1 = document.getElementById('ssn1');
    if(ssn1.value.length >= 6){
        document.getElementById('ssn2').focus();
    }
}

function ssnCheck(){
    const ssn1 = document.getElementById('ssn1');
    const ssn2 = document.getElementById('ssn2');
    const isSsn = document.getElementById('isSsn');

    if(ssn1.value == '' || ssn2.value == ''){
        alert('주민등록번호를 입력하세요.');
        ssn1.focus();
        return false;
    }

    // ssn1 = "001011", ssn2 = "3068518"
    const ssn = ssn1.value + ssn2.value;        // "0010113068518"
    const s1 = Number(ssn.substr(0, 1)) * 2;    // 0
    const s2 = Number(ssn.substr(1, 1)) * 3;
    const s3 = Number(ssn.substr(2, 1)) * 4;
    const s4 = Number(ssn.substr(3, 1)) * 5;
    const s5 = Number(ssn.substr(4, 1)) * 6;
    const s6 = Number(ssn.substr(5, 1)) * 7;
    const s7 = Number(ssn.substr(6, 1)) * 8;
    const s8 = Number(ssn.substr(7, 1)) * 9;
    const s9 = Number(ssn.substr(8, 1)) * 2;
    const s10 = Number(ssn.substr(9, 1)) * 3;
    const s11 = Number(ssn.substr(10, 1)) * 4;
    const s12 = Number(ssn.substr(11, 1)) * 5;
    const s13 = Number(ssn.substr(12, 1));

    let result = s1+s2+s3+s4+s5+s6+s7+s8+s9+s10+s11+s12;
    result = result % 11;
    result = 11 - result;
    if(result >= 10) {result = result % 10;}

    if(result == s13){
        alert('유효한 주민등록번호입니다.');
        isSsn.value = 'true';
    } else {
        alert('유효하지 않은 주민등록번호입니다.');
    }
}

function sample6_execDaumPostcode() {
    new daum.Postcode({
        oncomplete: function(data) {
            // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

            // 각 주소의 노출 규칙에 따라 주소를 조합한다.
            // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
            var addr = ''; // 주소 변수
            var extraAddr = ''; // 참고항목 변수

            //사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
            if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
                addr = data.roadAddress;
            } else { // 사용자가 지번 주소를 선택했을 경우(J)
                addr = data.jibunAddress;
            }

            // 사용자가 선택한 주소가 도로명 타입일때 참고항목을 조합한다.
            if(data.userSelectedType === 'R'){
                // 법정동명이 있을 경우 추가한다. (법정리는 제외)
                // 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
                if(data.bname !== '' && /[동|로|가]$/g.test(data.bname)){
                    extraAddr += data.bname;
                }
                // 건물명이 있고, 공동주택일 경우 추가한다.
                if(data.buildingName !== '' && data.apartment === 'Y'){
                    extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
                }
                // 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
                if(extraAddr !== ''){
                    extraAddr = ' (' + extraAddr + ')';
                }
                // 조합된 참고항목을 해당 필드에 넣는다.
                document.getElementById("sample6_extraAddress").value = extraAddr;
            
            } else {
                document.getElementById("sample6_extraAddress").value = '';
            }

            // 우편번호와 주소 정보를 해당 필드에 넣는다.
            document.getElementById('sample6_postcode').value = data.zonecode;
            document.getElementById("sample6_address").value = addr;
            // 커서를 상세주소 필드로 이동한다.
            document.getElementById("sample6_detailAddress").focus();
        }
    }).open();
}


** 실행결과

 


5. 이벤트(Event)

 : 웹 브라우저가 알려주는 HTMl 요소에 대한 사건의 발생을 의미한다.

   웹 페이지에 사용된 자바스크립트는 발생한 이벤트에 반응하여 특정 동작을 수행할 수 있다.

   따라서 자바 스크립트의 비동기식 이벤트 중심의 프로그램 모델이라고 합니다.

 


6. 이벤트 타입(Event Type)

 : 발생한 이벤트의 종류를 나타내는 문자열로 이벤트명이라고 한다.

   가장 많이 사용하는 키보드, 마우스, HTML, DOM, window 객체 등을 처리하는 이벤트가 폭넓게 제공되고 있다.

   https://developer.mozilla.org/en-US/docs/Web/Events

 

** 2_이벤트타입.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>이벤트 타입</title>
    <script>
        window.onload = function() {
            const text = document.getElementById('text');
            text.innerHTML = "<i>HTML 문서가 모두 로드되었습니다.</i>";
        }
    </script>
</head>
<body>
    <h2>이벤트 타입</h2>
    <p id="text"></p>
    <p onclick="changeText(this)">문자열을 클릭하세요.</p>
    <script>
        'use strict';
        function changeText(el) {
            el.innerHTML = "<b>문자열의 내용이 변경되었어요.</b>";
        }
    </script>
</body>
</html>

 

** 실행결과

 


7. 이벤트 타겟(Event Target)

 : 이벤트가 일어날 객체를 의미한다.

 


8. 이벤트 리스너(Event Listener)

 : 이벤트가 발생했을때 그 처리를 담당하는 함수를 의미한다.

   이벤트 헨들러라고도 부르며 지정된 타입의 이벤트가 특정 요소에서 발생하면,

   웹 브라우저는 그 요소에 등록된 이벤트 리스너를 실행한다.

 

** 이벤트 리스너로 만드는 방법
1) 프로퍼티로 이벤트를 등록하는 방법

   window.onload = function() {
       이벤트 실행문;
   }
   // 프로퍼티로 이벤트를 등록하는 방법은 모든 브라우저가 대부분 이벤트 타입으로 지원하고 있다.

   // 단점의 이벤트 타입별로 오직 하나의 이벤트 리스너만 등록할 수 있다는 점이다.

2) 객체나 요소의 메소드에 이벤트 리스너를 전달하는 방법

   이벤트타겟1.addEventListener(이벤트타입, 이벤트리스너);      // 등록
   이벤트타겟2.addEventListener(이벤트타입, 이벤트리스너);      // 등록


   이벤트타겟1.removeEventListener(이벤트타입, 이벤트리스너); // 제거

 

   function 이벤트리스너() {
       이벤트 실행문;
   }

 

** 3_이벤트리스너.html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>이벤트 리스너</title>
</head>
<body>
    <h2>이벤트 리스너</h2>
    <p><button id="eventBtn">이벤트 버튼</button></p>
    <p><button id="delBtn" onclick="delEvent()">이벤트 삭제 버튼</button></p>
    <p id="text"></p>
    <script>
        'use strict';
        const btn = document.getElementById('eventBtn');
        btn.addEventListener('click', clickBtn);
        btn.addEventListener('mouseover', mouseOverBtn);
        btn.addEventListener('mouseout', mouseOutBtn);

        function clickBtn(){
            document.getElementById('text').innerHTML = '<b>버튼을 클릭했어요</b>';
        }
        function mouseOverBtn(){
            document.getElementById('text').innerHTML = '<b>버튼 위에 마우스가 올라갔어요</b>';
        }
        function mouseOutBtn(){
            document.getElementById('text').innerHTML = '<b>버튼 밖으로 마우스가 나갔어요</b>';
        }

        function delEvent(){
            btn.removeEventListener('mouseover', mouseOverBtn);
            btn.removeEventListener('mouseout', mouseOutBtn);
            document.getElementById('text').innerHTML = '<b>이벤트 리스너가 삭제되었어요</b>';
        }
    </script>
</body>
</html>

 

 

9. 이벤트타겟, 이벤트명, 이벤트리스너 예시

 

 

10. 이벤트 객체(Event Object)

 : 이벤트 객체란 특정 타입의 이벤트와 관련이 있는 객체이다.

   이벤트 객체는 해당 타,입의 이벤트에 대한 상세정보를 저장하고 있다.

   모든 이벤트 객체는 이벤트 타입을 나타내는 type 프로퍼티와 이벤트 대상을 나타내는 target 프로퍼티를 가진다.

   이벤트 객체는 이벤트 리스너가 호출될 때 인수로 전달된다.

 

   <input type="button" onclick="sendit()" value="가입완료">


   function sendit(e) {        // e : 이벤트 객체
       console.log(e.target);  // 이벤트 타겟
       console.log(e.type);    // 이벤트 타입
   }

 

** 4_이벤트객체(1).html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>이벤트 객체 - 1</title>
</head>
<body>
    <h2>이벤트 객체 - 1</h2>
    <input type="button" id="btn" value="버튼">
    <script>
        'use strict';
        const btn = document.getElementById('btn');
        btn.addEventListener('click', clickBtn);

        function clickBtn(e) {
            console.log(e.target);
            console.log(e.target.id);
            console.log(e.target.value);
            console.log(e.type);
        }
    </script>
</body>
</html>

 

** 실행결과

** 5_이벤트객체(2).html

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>이벤트 객체 - 2</title>
</head>
<body>
    <h2>이벤트 객체 - 2</h2>
    <input type="button" id="btn1" value="버튼1">
    <input type="button" id="btn2" value="버튼2">
    <input type="button" id="btn3" value="버튼3">
    <script>
        'use stirct';
        const btn1 = document.getElementById('btn1');
        const btn2 = document.getElementById('btn2');
        const btn3 = document.getElementById('btn3');

        btn1.addEventListener('click', clickBtn);
        btn2.addEventListener('click', clickBtn);
        //btn3.addEventListener('click', clickBtn);
        //btn3.addEventListener('click', function() {
        //    console.log('버튼 3가 눌렸어요.');
        //});
        //btn3.addEventListener('click', () => {
        //    console.log('버튼 3가 눌렸어요.');
        //});
        btn3.addEventListener('click', (event) => {
            console.log(`${event.target.id}가 눌렸어요.`);
        });

        function clickBtn(e) {
            switch(e.target.id) {
                case "btn1":
                    console.log('버튼 1이 눌렸어요!');
                    break;
                case "btn2":
                    console.log('버튼 2가 눌렸어요!')
                    break;
                case "btn3":
                    console.log('버튼 3가 눌렸어요!')
                    break;
            }
        }
    </script>
</body>
</html>

 

** 실행결과

 

 

11. 이벤트 전파

 : 이벤트 전파란 이벤트가 발생했을때 브라우저가 이벤트 리스너를 실행시킬 대상 요소를 결정하는 과정을 의미한다.

   이벤트의 대상이 window 객체와 같은 단일 객체라면 이벤트의 전파는 일어나지 않는다.

   하지만 document 객체나 HTML 문서의 요소에서 이벤트가 일어나면 대상 요소를 결정하기 위해

   이벤트의 전파가 일어난다.

   이벤트 전파 방식은 버블링 전파 방식과 캡처링 전파방식으로 나뉜다.

1) 버블링 전파방식

 : 이벤트가 발생한 요소부터 시작하여 DOM 트리에 따라 위쪽으로 올라가며 전파되는 방식


2) 캡처링 전파방식

 : 이벤트가 발생한 요소까지 DOM트리의 최상위부터 아래쪽으로 내려가며 전파되는 방식이다.

   addEventListener() 메소드의 세번째 인수에 true를 전달하면 된다.


3) 전파 막기 : event객체.stopPropagation();

<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>이벤트 전파</title>
    <style>
        #divBox {
            width: 100%;
            height: 100px;
            border: 3px solid red;
        }
        #pBox {
            width: 70%;
            height: 50px;
            border: 3px solid blue;
        }
        #spanBox {
            border: 3px solid green;
        }
    </style>
</head>
<body>
    <h2>이벤트 전파</h2>
    <div id="divBox">
        <p id="pBox">박스 안의 여러 곳을 <span id="spanBox">클릭</span>하세요.</p>
    </div>
    <p id="text"></p>
    <script>
        // 버블링 전파방식
        //document.getElementById('divBox').addEventListener('click', clickDiv);
        //document.getElementById('pBox').addEventListener('click', clickP);
        //document.getElementById('spanBox').addEventListener('click', clickSpan);

        // 버블링 전파방식
        //function clickDiv(e){
        //    document.getElementById('text').innerHTML += 'div 요소를 클릭했어요.<br>';
        //}

        // 캡처링 전파방식
        document.getElementById('divBox').addEventListener('click', clickDiv, true);
        document.getElementById('pBox').addEventListener('click', clickP, true);
        document.getElementById('spanBox').addEventListener('click', clickSpan, true);

        function clickDiv(e){
            document.getElementById('text').innerHTML += 'div 요소를 클릭했어요.<br>';
            e.stopPropagation();
        }
        function clickP(e){
            document.getElementById('text').innerHTML += 'p 요소를 클릭했어요.<br>';
        }
        function clickSpan(e){
            document.getElementById('text').innerHTML += 'span 요소를 클릭했어요.<br>';
        }
    </script>
</body>
</html>



12. 지금까지 배운 자바스크립트는 Vanilla JS, ECMA 6 표준 방식이다.

'웹_프론트_백엔드 > 프론트엔드' 카테고리의 다른 글

2021.01.16  (0) 2021.01.16
2021.01.10  (0) 2021.01.11
2020.09.26  (0) 2020.09.28
과제-주민등록번호 검증 페이지 작성  (0) 2020.09.25
2020.09.20  (0) 2020.09.22