FrontEnd/JavaScript

#42. JavaScript(객체2, window객체, 이벤트)

열하나요 2023. 8. 30. 17:38

Java Script에서는

get은 객체명.속성명이고

set은 객체명.속성명(getter)에 =(대입연산자)로 대입해주면 되는 것 같다.

 

42-1. 객체2

<!DOCTYPE html>
<html lang="en">
<head>
    <title>객체는 사실 별로 쉽지않음...</title>

    <style>
        .area{
            background-color: lemonchiffon;
            border : 1px solid blanchedalmond;
            height : 300px;
        }
    </style>
</head>
<body>

    <h1>객체2</h1>

    <h3>* 객체배열을 이용한 다량의 데이터 관리</h3>

    <!-- 객체들을 배열에 넣은 것 -->

    <button onclick="test1();">확인</button>
    <div id="area1" class="area"></div>

    <script>
        function test1(){

            // 학생 객체 만들기
            var student0 = {name : '이땡철', java : 50, oracle : 40, html : 100, css : 20};
            var student1 = {name : '제임스고슬림', java : 100, oracle : 100, html : 20, css : 10};
            var student2 = {name : '홍길동', java : 20, oracle : 20, html : 20, css : 20};
            var student3 = {name : '유아리', java : 100, oracle : 100, html : 100, css : 100};

            // 학생 객체를 담을 배열만들기(빈배열)
            let students = [];

            // 배열에 객체 추가하기
            // 자바스크립트에서 배열에 요소를 추가할 때 index, push, unshift, (slice도 되겠지?)

            students.push(student0); // 0번
            students.push(student1); // 1번
            students.push(student2); // 2번
            students.push(student3); // 3번

            console.log(students);
            console.log(students[1].java);

            // javascript : 100점
            // 합계를 구해주는 기능
            // 평균을 구해주는 기능

            for(let i in students){
                students[i].javascript = 100;
                students[i].getSum = function(){
                    return this.java + this.oracle + this.html + this.css + this.javascript;
                }
                students[i].getAvg = function(){
                    return this.getSum() / 5;
                }
            };

            console.log(students);

            // 전체 학생들의 이름, 총점, 평균 div 요소에 출력하기 시작!
            const area1 = document.getElementById('area1');
            
            for(let i in students){
                area1.innerHTML += '이름 : ' + students[i].name + '<br>';
                area1.innerHTML += '총점 : ' + students[i].getSum() + '<br>';
                area1.innerHTML += '평균 : ' + students[i].getAvg();
            }

            /* 쌤꺼
            for(let i in students){
                arae.innerHTML += '이름 : ' + student[i].name 
                              + ', 총점 : ' + students[i].getSum() + 
                              ', 평균 : ' + student[i].getAvg() + '<br>';
            }
            */

        }
    </script>

    <hr>

    <h3>* 생성자 함수</h3>
    <p>
        new 키워드를 사용해서 객체를 생성할 수 있는 함수를 의미 <br>
        (함수명을 만들 때 첫 글자를 대문자로 만듦)
    </p>

    <button onclick="test2();">실행</button>
    <div id="area2" class="area"></div>

    <script>
        function test2(){

            var student0 = new Student('홍길동', 30, 40, 20, 30, 50);
            var student1 = new Student('제임스고슬림', 100, 100, 100, 100, 100, );
            var student2 = new Student('어쩌고저쩌고', 20, 30, 40, 50, 60);

            // 배열에 담기
            let students = [student0, student1, student2];

            // 반복문 이용해서 출력
            for(let i in students){
                document.getElementById('area2').innerHTML += students[i];
            }

            // 생성자 함수
            function Student(name, java, oracle, html, css, javascript){

                // this = {}; // 기본생성자(?)

                // Property 초기화
                this.name = name;
                this.java = java;
                this.oracle = oracle;
                this.html = html;
                this.css = css;
                this.javascript = javascript;

                // return this;

                // => 이거랑 같지
                /*
                this = {
                    name : '홍길동',
                    java : 30,
                    oracle : 40,
                    html : 20,
                    css : 30,
                    javascript : 50
                }
                */

                // 메소드 속성 정의
                this.getSum = function(){
                    return this.java + this.oracle + this.html + this.css + this.javascript;
                }

                this.getAvg = function(){
                    return this.getSum() / 5;
                }

                this.toString = function(){
                    return '이름 : ' + this.name + ', 총점 : ' + this.getSum() + ', 평균 : '
                            + this.getAvg() + '<br>';
                }
            }
            console.log(student0); // 원래는 {~~}만 나오는데 얘는 Student {~~} 이렇게 나옴
        }
    </script>

    <hr>

    <h3>* Date 객체</h3>

    <button onclick="test3();">실행</button>
    <div id="area3" class="area"></div>

    <script>
        function test3(){

            const area3 = document.getElementById('area3');

            // Date 객체 생성 => new Date();
            const date1 = new Date(); // 현재 날짜 및 시간

            // area3에 출력
            area3.innerHTML += 'date1 : ' + date1 + '<br>';

            // 2023년 12월 12일로 세팅
            const date2 = new Date(2023, 12-1, 12);
            area3.innerHTML += 'date2(종강일) : ' + date2 + '<br>';
            // 월의 경우 내부적으로 +1되기 때문에 해당 월(숫자) -1을 해줘야 함!

            // 2023년 12월 12일 시간까지 세팅
            const date3 = new Date(2023, 12-1, 12, 17, 50, 0);
            area3.innerHTML += 'date3(종강일) : ' + date3 + '<br>';

            // ms까지 세팅하려면??
            // 1000ms == 1초
            const date4 = new Date(2023, 12-1, 12, 17, 50, 0, 5000);
            area3.innerHTML += 'date4(종강일) : ' + date4 + '<br>';

            // 종강일까지 디데이 구하기
            let now = new Date();
            let end = new Date(2023, 12-1, 12);
            area3.innerHTML += '종강일 디데이 : ' + (end - now) + '<br>';

            // 1s == 1000ms
            // 1m == 60s == 60 * 1000ms
            // 1h == 60m == 60 * 60s == 60 * 60 * 1000ms
            // 1d == 24h == 24 * 60m == 24 * 60 * 60s == 24 * 60 * 60 * 1000ms
            let dday = (end - now) / (24 * 60 * 60 * 1000);
            alert('종강까지 ' + Math.ceil(dday) + '일 남았습니다.');

            // 년도만 알아내고 싶다면 : getFullYear()
            area3.innerHTML += '연도 : ' + date1.getFullYear() + '<br>';
            // 월만 알아내고 싶다면 : getMonth();
            area3.innerHTML += '월 : ' + (date1.getMonth() + 1) + '<br>';
            // 일만 알아내고 싶다면 : getDate();
            area3.innerHTML += '일 : ' + date1.getDate() + '<br>';

            // 추가적으로
            // 시 : getHours(), 분 : getMinutes(), 초 : getSeconds()

            // 요일만 알아내고 싶다면 : getDay(); 0 == 일요일, 1 == 월요일, 2 == 화요일
            area3.innerHTML += '요일 : ' + date1.getDay() + '<br>';

        }
    </script>
    
</body>
</html>

 

42-2. window객체

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>window 객체</title>

    <style>
        body{
            background-color: lightgreen;
            color : rgb(rgb(230, 111, 200), rgb(238, 250, 250), rgb(123, 123, 123));
        }
        .area{
            width : 300px;
            height : 100px;
            background: bisque;
            border : 1px solid forestgreen;
            font-size : 50px;
        }
        .small{
            height : 150px;
        }
        .big{
            height : 300px;
        }
    </style>
</head>
<body>

    <h1>window객체</h1>

    <p>
        window 객체는 자바스크립트 최상위 객체 크게 BOM과 DOM으로 나뉨 <br><br>

        - BOM(Browser Object Model) : 브라우저 창과 관련된 객체들 <br>
        - DOM(Document Object Model) : HTML 문서의 요소(태그) 관련된 객체들
    </p>

    <hr>

    <h3>window객체에서 제공하는 메소드</h3>

    <!--
        window.alert();
        window.console.log();
        window.confirm();
        window.prompt();
    -->

    <h3>window.open()</h3>

    <button onclick="test1();">네이버</button>

    <script>
        function test1(){

            // window.open();

            window.open('http://www.naver.com', 'ㅋㅋㅋㅋㅋㅋㅋ');

            // window.open('url', '창이름', '창의특성');
            // 창이름 : 창 이름이 동일한 게 이미 열려있을 경우 새롭게 열리지않고 이미 열린 window에서 새로고침
            //          (브라우저마다 새로고침 / 새 탭)
            // 창의특성 : 새로 열릴 창의 너비, 높이, 툴바, 스크롤바, 상태표시줄 등등(브라우저마다 다름)

            /*
                * 창의 특성
                => px
                width : 창의 가로길이
                height : 창의 세로길이

                => yes / no
                resizable : 창의 크기 조절 여부
                location : 주소창을 보일것인지 안보일것인지
                menubar : 메뉴바를 보일것인지 안보일것인지
                scrollbar : 스크롤바를 보일것인지 안보일것인지
                status : 상태표시줄
                toolbar : 도구모음

                여러 속성을 한 번에 지정하고 싶다면, ,로 나열한다
                '속성=속성값, 속성=속성값, ...'
            */

            window.open('http://www.naver.com', 'a', 'width=500, height=500, resizable=no, location=no, menubar=no, scrollbar=no, status=no, toolbar=no');
            // 브라우저에 따라 적용이 안되는 속성이 많다.
        }
    </script>

    <hr>

    <h4>- window.setTimeout(함수, ms);</h4>

    <button onclick="test2();">실행</button>

    <script>
        function test2(){

            // alert('하이하이~');

            // 3초 뒤에 alert이 뜨게끔
            /*
            window.setTimeout(function(){
                alert('나는 3초를 기다려야뜸!');
            }, 3000);
            */

            var newWindow = window.open(); // 새로 열린 창의 window객체
            newWindow.alert('버튼을 누르면 3초뒤에 페이지가 닫힙니다!');
            
            window.setTimeout(function(){
                newWindow.close();
            }, 3000);

            // setTimeout : 내가 세팅한 일정 시간 후에 "단 한번"만 핸들러를 수행
            
        };

    </script>

    <hr>

    <h4> window.setInterval(함수, ms)</h4>

    <button onclick="test3();">실행</button>
    <div id="area1" class="area"></div>

    <script>
        function test3(){

            const area1 = document.getElementById('area1');

            var count = 1;
            window.setInterval(function(){
                // area1.innerHTML += '<span style="color:red">여러분 점심 뭐드셨어요?</span>';
                // area1.innerHTML = count++;

                // 시계만들기

                // 출력형식
                /*
                시 : 분 : 초
                02 : 08 : 55 오전오후
                */
                
                // 내가한거
                /*
                let clock = new Date();

                if(clock.getHours() > 12){
                    var hours = clock.getHours() - 12;
                    var de = '오후';
                } 
                else {
                    var hours = clock.getHours();
                    var de = '오전';
                }
                area1.innerHTML = hours + ' : ' + clock.getMinutes() + ' : ' + clock.getSeconds() + ' ' + de;
                */

                // 쌤꺼
                var date = new Date();

                hour = date.getHours();
                min = date.getMinutes();
                sec = date.getSeconds();

                if(sec < 10){
                    sec = '0' + sec;
                }
                if(min < 10){
                    min = '0' + min;
                }
                if(hour > 12){
                    ap = 'PM';
                    hour -= 12;
                }
                else{
                    ap = 'AM';
                }

                area1.innerHTML = hour + ' : ' + min + ' : ' + hour + ' ' + ap;

            }, 1000);

            // setInterval : 내가 지정한 간격마다 "매 번" 핸들러 수행
            
        }
    </script>

    <hr>

    <h1>* BOM(Browser Object Model</h1>

    <p>
        location, screen, navigator <br>
        location만 잘 알아도 될 정도로 많이씀
    </p>

    <button onclick="console.log(location)">실행</button>

    <br><br>
    <h3>location객체</h3>
    <p>
        브라우저의 주소창 관련된 객체 => url(href속성)
    </p>

    <a href="http://www.naver.com">네이버로이동</a>
    <!-- a태그는 애초에 클릭 시 요청할 url을 작성할 수 있는 href속성을 제공함 -->

    <button onclick="location.href='http://www.naver.com'">나는 무슨일이 일어날까?</button>
    <!-- 굳이 a태그를 사용하지 않더라도 url요청을 보낼 수 있음 -->

    <label onclick="loc();">네이버로 이동</label>
    <br><br>

    <script>
        function loc(){
            // 간단하게 a태그로 url을 요청할 수 있지만, 함수를 쓰는 이유는 
            // db에서 가져온 pk값등을 주소에 붙여 같이 url을 요청해야 하므로 함수를 쓴다(왜냐면 조건문같은 걸 써야할 수도 있고, 변수를 써야할수도 있잖애)
            location.href = 'http://www.naver.com';
        }
    </script>

    <hr>

    <button onclick="location.reload();">새로고침</button>
    <button onclick="location.href=location.href">새로고침</button>

    <!-- assign, replace -->
    <button onclick="location.assign('http://www.google.com')">구글로이동</button> <!--이동 --> 
    <button onclick="location.replace('http://www.google.com')">구글로 이동</button> <!-- 치환 -->
    <!-- replace는 뒤로가기를 사용할 수 없음 -->

    <hr>

    <h3>screen객체</h3>
    <button onclick="console.log(screen);">screen</button> <!-- 사용자가 보는 화면에 대한 정보 -->

    <h3>navigator객체</h3>
    <button onclick="console.log(navigator);">navi</button> <!-- 브라우저에 대한 정보 -->

    <hr>

    <h1>* DOM(Document Object Model</h1>

    <p>
        - HTML문서가 포함하고 있는 각각의 요소를 Node(노드)라고 한다. <br>
        - 요소 노드(Element Node) : 태그 자체만을 의미 <br>
        - 텍스트 노드(Text Node) : 태그 내에 기록되는 내용 <br>

        텍스트노드가 존재하지 않는 요소(시작태그만 있는 요소들) : input, img, ... <br>
        텍스트노드가 존재하는 요소(시작 태그와 종료 태그가 한 쌍인 요소) : div, button, a, h1, p, ...
    </p>

    <button onclick="test4();">실행</button>
    <div id="area3" class="small">

    </div>

    <script>
        function test4(){

            // 동적으로 요소만들기!(처음 문서 로딩시에는 존재하지 않다가 나중에 만들어지는 요소)
            /*
                <h3>
                    안녕하세요
                </h3>
            */
           
            // 1. '문자열'로 만드는 방법
            document.getElementById('area3').innerHTML = '<h3>안녕하세요</h3>';

            // 2. document객체에서 제공하는 메소드를 통해 '요소객체'로 만드는 방법 
            // 원래 보통 깜빡! 하면서 화면이 바뀌는데 그걸 없앴다!!! 근데 좀 복잡함
            // 2_1) elementNode 객체 생성 : document.createElement('태그명');
            let elementNode = document.createElement('h3');
            console.log(elementNode);
            console.log(typeof(elementNode));
            // 2_2) textNode 객체 생성 : document.createTextNode('문구');
            let textNode = document.createTextNode('안녕하세요');
            console.log(textNode);
            console.log(typeof(textNode));

            // 3) 두 개의 노드를 연결(ElementNode의 자식으로 TextNode를 추가)
            // a의 자식으로 b를 추가
            // 요소노드.appendChild(텍스트노드);
            elementNode.appendChild(textNode);

            console.log(elementNode);

            // innerHTML은 반드시 문자열형태로 넣어야함!!
            document.getElementById('area3').innerHTML = elementNode.toString();

            // div요소의 자식으로 elementNode를 추가
            document.getElementById('area3').appendChild(elementNode);
        }
    </script>

    <hr>

    <h4>- 텍스트노드가 존재하지 않는 노드 생성(빈 태그들)</h4>

    <button onclick="test5();">실행</button>
    <div id="area5" class="big"></div>

    <script>
        function test5(){

            var img = document.createElement('img'); // <img>

            // <img src='경로', width='가로길이' height='세로길이' alt='설명'>
            // 속성추가
            // 추가하는 방법 : 객체명.속성명 = 값

            img.src = 'https://kh-academy.co.kr/resources/images/main/logo.svg';
            img.width = '720';
            img.height = '720';

            console.log(img);
            document.getElementById('area5').appendChild(img);
        };
    </script>

</body>
</html>

 

42-3. 이벤트

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>이벤트</title>

    <style>
        .area{
            background-color :beige;
            border : 1px solid lightpink;
            height : 100px;
        }

        .style{
            display : none;
            background-color : orangered;
        }
    </style>

</head>
<body>

    <h1>이벤트</h1>

    <h2>1. 이벤트 모델 종류(이벤트를 부여하는 방법들)</h2>

    <!-- 
        * 이벤트 관련 용어
        event target : 이벤트가 일어날 객체(button, h1, label, ...)
        event type : 이벤트 종류(click, scroll, mousemove)
        event handler : 이벤트가 발생했을 때 동작할 코드들의 모임
        
        * 이벤트 모델 종류
        1. 고전 이벤트 모델 => btn.onclick = function(){}
        2. 인라인 이벤트 모델 => <button onclick="함수();"></button> <script>...</script>
        3. 표준 이벤트 모델 => addEventListener를 사용하는 방법
    -->

    <h3>* 고전 이벤트 모델(기본 이벤트 모델)</h3>
    <p>
        요소 객체를 가지고 와서 해당 요소객체의 이벤트 속성에 접근한 후 <br>
        이벤트 핸들러를 연결하는 방식(== 익명함수를 대입할 것!) <br><br>

        객체.(이벤트)속성명 = function(){}; <br>
        => null을 대입하면 이벤트가 제거됨! <br>
    </p>

    <button id="btn1">실행</button>
    <button id="btn2">실행</button>
    <div id="area1" class="area"></div>

    <script>
        const area1 = document.getElementById('area1');

        /*
        // target(이벤트가 발생할 객체) 접근하기
        const btn1 = document.getElementById('btn1');
        // 이벤트 부여
        btn1.onclick = function(){ // 이벤트 핸들러
            area1.innerHTML = 'btn1클릭~ <br>';
        };
        */
        document.getElementById('btn1').onclick = function(){
            area1.innerHTML = 'btn1클릭 ~ <br>';
            console.dir(document.getElementById('btn1')); // onclick 속성에 f()함수가 있음
        };

        document.getElementById('btn2').onclick = function(){
            // btn2를 클릭하면 btn1의 이벤트를 제거
            document.getElementById('btn1').onclick = null; //이벤트 제거
            area1.innerHTML += 'btn2를 클릭해서 btn1의 이벤트 제거';
            // 이벤트를 제거한 후 btn1을 클릭하면 아무일도 일어나지 않음
        }
    </script>

    <hr>

    <h3>* 인라인 이벤트 모음</h3>

    <p>
        요소 내부에 직접적으로 이벤트 속성을 제시해서 실행할 내용을 정의하는 방식 <br>
        주로 script 태그 내에 정의 되어 함수를 호출하는 방법을 선호
    </p>

    <button onclick="document.getElementById('area2').innerHTML = '버튼클릭<br>'; alert('이벤트실행');">실행</button>
    <div id="area2" class="area"></div>

    <!-- 
        요소 내부에 직접적으로 이벤트를 기술하면 실행하는 것에는 문제가 없음
        한 줄의 내용이 길어지고(가독성이 떨어짐) 복잡하므로 잘 사용하지 않음!!
    -->

    <button onclick="test1();">두 번째 버튼</button>

    <script>
        function test1(){
            document.getElementById('area2').innerHTML = '두 번째 버튼클릭 ~ <br>';
        }
    </script>

    <h3>* 표준 이벤트 모델(addEventListener)</h3>
    <!-- 브라우저마다 안도는 곳이 있음(하지만 가장 선호하는 모델) ex.....익스플로어-->

    <pre>
        [ 표현법 ]
        이벤트를 부여하고자 하는 요소객체.addEventListener('이벤트명', 이벤트핸들러 => 익명함수);
    </pre>

    <button id="btn3">실행</button>

    <script>
        // document.getElementById('아이디값').addEventListener('이벤트타입', '이벤트핸들러');

        const btn3 = document.getElementById('btn3');

        btn3.addEventListener('click', function(){
            alert('표준 이벤트 모델 테스트');
        });

        // mouseenter : 버튼 안으로 포인터가 들어가는 순간(≒hover)
        btn3.addEventListener('mouseenter', function(){
            // btn3.style.backgroundColor = 'yellowgreen'; // 실무에서 잘안씀
            btn3.classList.add('style'); // 이렇게 하면 class를 먹이게 되는것! => class가 'style'인 속성을 가져오게 됨
        });

        // mouseout : 버튼 밖으로 포인터가 빠져나가는 순간
        btn3.addEventListener('mouseout', function(){
            // btn3.style.backgroundColor = 'lightpink'; // 실무에서 잘안씀
            btn3.classList.remove('style')
        })
    </script>

    <hr>

    <h3>2. 현재 이벤트가 발생한 해당 요소객체(타켓)에 접근하는 방법</h3>

    <button id="btn4">고전이벤트방식</button>
    <button id="btn5">표준이벤트방식</button>

    <button onclick="test2();">인라인이벤트방식</button>

    <button onclick="test3(this);">코카콜라</button>
    <button onclick="test4();">펩시콜라</button>


    <script>

        // 함수 호출 시 이벤트가 발생한 요소를 console창에 찍어야함!
        function test3(e){
            console.log(window.event.target);
            console.log(e);
        }

    </script>


    <script>
        // 고전이벤트 방식
        document.getElementById('btn4').onclick = function(e){
            // 이벤트 종류를 알 수 있는 방법
            // 방법1) 
            console.log(window.event);
            // PointerEvent, MouseEvent 객체
            // 마우스를 이용한 이벤트 발생 시!

            // 방법2)
            console.log(e);
            // 이벤트 발생 시 내부적으로 eventTarget을 매개변수에 전달

            // window.event == e
            // 이벤트 종류로부터 target을 알아내려면?
            console.log(window.event.target);
            console.log(e.target);
            console.log(this);

            // window.event.target == e.target == this == 현재 이벤트가 발생한 요소 객체

            window.event.target.style.backgroundColor = 'red';
            e.target.innerHTML = '버튼클릭';
            this.style.color = red;
        };

        // 표준이벤트 방식
        document.getElementById('btn5').addEventListener('click', function(e){
            // window.event.target == e.target == this

            window.event.target.style.backgroundColor = 'black';
            e.target.innerHTML = '이벤트발생';
            this.style.color = 'white';
        });

        // 인라인 이벤트 방식
        function test2(e){
            console.log(window.event.target);

            console.log(this); // 사용불가 : 선언적함수에서의 this는 window객체를 가리킴
            // console.log(e.target); // 사용불가 : 인라인 방식은 태그내에서 직접 호출이기 때문 (사실상 undefined)
            
            // 일반 선언적 함수를 호출할 때는 window.event.target밖에 없음!
        }

    </script>

    <hr>

    <h2>3. 태그별 기본적으로 가지고 있는 이벤트 제거</h2>

    <p>
        기본적으로 이벤트를 가지고 있는 요소 <br>
        - a 태그 : 클릭 시 href속성에 제시되어있는 url로 요청을 하는 기본이벤트 보유 <br>
        - form 태그 내의 submit버튼 : 클릭시 사용자가 입력한 정보들을 action속성에 제시되어있는
                                     url로 제출하면서 요청을 보내는 기본이벤트가 보유 <br><br>

        기본 이벤트를 제거하고자 한다면
        => 이벤트 핸들러 return값을 false가 리턴되게 하면 기본이벤트가 실행만 됨
    </p>

    <a href="http://www.naver.com" onclick="alert('ㅎㅎㅎㅎ');">네이버로</a>

    <br>

    <!-- 어마어마하게 사용하게 될 예정~~ ♤♠♤♠♤♠♤♠♤♠♤♠♤♠♤♠♤♠♤♠♤♠♤♠♤♠♤♠♤♠♤♠♤♠♤♠ -->
    <!-- 방법 1. return false로 onclick속성안에 붙여준다. -->
    <a href="http://www.naver.com" onclick="test4(); return false;">네이버로</a>

    <!-- 방법 2. return 함수 호출 -->
    <a href="http://www.naver.com" onclick="return test4();">네이버로</a>

    <script>
        function test4(){
            alert('ㅎㅎㅎㅎ');
            // return; // 생략되어 있음(호출한 곳으로 돌아가서 href주소로 이동)
            return false;
        }
    </script>

    <br><br><br>

    <hr>

    <br><br><br>

    <form action="test.do">

        <h3>회원가입 양식</h3>

        아이디 : <input type="text" name="userId" id="userId"> <br>
        <label style="font-size : 10px; color:lightslategray;">
            영문자 또는 숫자로만 총 5 ~ 12자 사이로 입력해 주세요.
        </label> <br>

        비밀번호 : <input type="password" name="userPwd" id="userPwd"> <br>
        비밀번호확인 : <input type="password"> <br>

        <!-- 유효성 검사 해주는 함수 : validate(); -->
        <input type="submit" value="회원가입" onclick="return validate();">

    </form>

    <script>
        function validate(){

            let userId = document.getElementById('userId').value;
            let userPwd = document.getElementById('userPwd').value;

            console.log(userId);

            // 1. 글자수 검사

            /*
            if(userId.length >= 5 && userId.length <= 12){ // 글자수가 적합했을 경우
                return;
                for(let i = 0; i < userId.length; i++){
                    if(userId.charAt(i) >= 'a' && userId.charAt(i) <= 'z' ||
                       userId.charAt(i) >= 'A' && userId.charAt(i) <= 'Z' ||
                       userId.charAt(i) >= 0 && userId.charAt(i) <= 9){
                        return true;
                    }
                    else{
                        return false;
                    }
                }
            }
            */

            // 아이디에 대한 유효성 검사
            // 영문자 또는 숫자로만 5 ~ 12자 사이인지 아닌지 판단
            // 로직이 복잡하고 귀찮음 => 유효성 검사를 정규표현식을 이용해서 해보자!

            // 정규표현식으로 간단하게 유효성검사

            var regExp = /^[a-zA-Z0-9]{5,12}$/;

            // 패턴을 만족하는지 검사 => 정규표현식 객체에서 제공하는 test()이용

            if(!regExp.test(userId)){
                alert('유효한 아이디가 아닙니다. 다시 입력해 주세요!');
                return false;
            }
            return true;
        }
    </script>
    
</body>
</html>