본문 바로가기
HTML,CSS,JavaScript

JavaScript DOM과 이벤트처리, 유효성 검증

by 히예네 2023. 5. 10.
728x90
반응형

DOM (document object model) 문서 객체 모델

 

DOM은 HTML문서의 계층적인 구조를 tree로 표현한다.

HTML, 문서를 객체로 표현한것을 DOM이라고 한다.

DOM은 웹브라우저의 하얀색 영역을 담당한다. BOM은 웹브라우저를 객체로 표현한것이다.

DOM과 BOM 차이점

DOM은 현재 보이는 하얀창을 제어한다면, BOM은 window속성에 속하여 웹 전체를 제어한다.

(DOM은 BOM안에 있는 것이다. )

HTML 요소 찾기

id나 tag로 찾는다. (안드로이드는 findViewById나 뷰바인딩으로 찾았다.)

tag는 s가 붙는다. 같은 tag가 많다.

 

DOM tree 순회

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>DOM</title>
    </head>
    <body>
        <!-- DOM : HTML 웹 문서안에 있는 것들을 객체로 바라보고 모델링한것  -->
        <!-- 트리구조를 구성하는 것들을 노드 node라고 부름 -->
        <!-- node의 종류는 3 종류 : element node, attribute node, text node -->

        <!-- node 타입 확인하기 -->
        <p id="p1"><a href="" target="">Google</a></p>
        
        <script>
            //id값이 p1인 요소를 찾자
            //document는 html의 하얀색 
            var e = document.getElementById('p1');
            //alert(e.nodeType+" : "+e.nodeName); //노드타입 1 : element 요소 노드, 요소이름 p
            
            //p요소의 속성을 알아보자
            var attrs = e.attributes; //너의 속성들을 줘봐
            //alert(attrs[0].nodeType+" : "+attrs[0].nodeName); //노드타입 2, 노드이름 id
            //alert("속성값 : "+attrs[0].value);

            //p요소의 첫번째 자식 노드 찾기
            var e = e.firstChild;//너의 첫자식 줘바 : a 요소노드
            //alert(e.nodeName+" : "+e.nodeType);

            //a 요소 속성값들
            var attrs=e.attributes;
            //alert(attrs[0].nodeType+ " : "+ attrs[0].nodeName);
            //alert(attrs[1].nodeType+ " : "+ attrs[1].nodeName);

            //a요소의 첫번째 자식노드 : text node
            var t = e.firstChild;
            alert(t.nodeType+" : "+t.nodeName) //노드 타입 3, 노드이름 #text
            alert("텍스트 값 : "+t.data); //data 자동완성 안됨. 

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

DOM 제어

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>js dom control</title>
    </head>
    <body>
        <!-- 요소의 속성을 변경 -->

        <!-- 1. img요소의 src 속성을 변경해보자 -->
        <img src="./image/img001.jpg" alt="img001" width="300" id="aa">
        <button onclick="changeImage()">change image</button> 
        <!-- 버튼눌렀을때 발동해야한다 onclick -->
        <script>
            function changeImage(){
                document.getElementById("aa").src="./image/m_m03.jpg";
            }
        </script>
        <hr>
        <!-- 요소의 스타일 변경 : id가 아니라 DOM tree구조를 이용해서 요소 접근해보자-->
        <p id="p1">this is paragraph</p>
        <button onclick="clickBtn(this)">스타일 변경</button> 
        <!-- 여기서 this는 버튼 -->
        <script>
            function clickBtn(e){
                //여기서 e는 버튼 
                //클릭된 버튼의 앞 형제 요소를 찾기
                var p = e.previousElementSibling;
                p.style.color = "red";
                p.style.fontWeight = "bold";
                p.style.fontStyle = "italic"; //개별선택자가 우선적용된다.
                //인라인이 우선적용되서 밑에 통짜 class는 적용이 안됬다. 
            }
        </script>


        <!-- class속성을 이용하여 다중스타일 한방에 적용
             class:어떤요소에 그룹을 만들어줌 -->
        
        <style>
            .kk{
                color: blue;
                font-weight: bold;
                font-style: italic;
            }
        </style>
        <button onclick="clickBtn2()">클래스 속성으로 다중 스타일 한방에 변경</button>
        <script>
            function clickBtn2(){
                document.getElementById('p1').style="";
                document.getElementById('p1').className ="kk";
                //유별남 class가 아니라 className으로 적용해야함
            }
        </script>
        <hr>
        <h1>DOM 노드로 추가 삭제 해보기</h1>
        <!-- DOM노드의 동적인 추가와 삭제 -->
        <button onclick="addText()">텍스트 추가</button>
        <button onclick="addElement()">요소 추가</button>
        <button onclick="removeNode()">자식 노드 제거</button>
        <p id="pp"></p>

        <script>
            function addText(){
                // var node = document.createTextNode('this is test ');
                // var node = document.createTextNode("<a href=''> this is test </a>"); //이러면 텍스트로만 인식한다.
                // var pp = document.getElementById('pp')
                // pp.appendChild(node); //append는 계속 추가됨 

                //위 작업 (텍스트노트 추가)을 간략하게.. 하는 속성
                var pp = document.getElementById('pp').textContent+="<a href=''> this is test </a>";
                
            }

            function addElement(){  
                // var node = document.createElement('a');
                
                // //속성노드 추가
                // var attr = document.createAttribute('href');
                // attr.value = "https://www.google.com";
                // node.setAttributeNode(attr);

                // //엥커에 보여줄 text가 필요하다
                // var text = document.createTextNode("구글");
                // node.appendChild(text);

                // document.getElementById('pp').appendChild(node);
                //요소 추가를 한방에 축약형으로...
                document.getElementById('pp').innerHTML+="<a href=''> this is test </a>";
            }

            function removeNode(){
                var pp = document.getElementById('pp');
                pp.removeChild(pp.firstChild);
            }
        </script>
        <hr>

        <!-- JS에서 요소를 찾을때 CSS 선택자 문법을 이용하여 요소를 접근/ 아이디# 클래스. -->
        <h3 id="ee">Hello world</h3>
        <button onclick="aa()">버튼</button> 
        <!-- onclick에서 ()빼면 안돼  -->
        <script>
            function aa(){
                var e = document.querySelector('#ee'); //css문법의 id선택자
                e.innerHTML="nice to meet you";
                
            }
        </script>
        <hr>
        <h4>aaa</h4>
        <h4>bbb</h4>
        <h4>ccc</h4>
        <button onclick="bbb()">버튼</button>
        <script>
            function bbb(){
                //css선택자 중에서 여러 요소가 찾아지는 선택자들
                //class , tag, * 등 
                //타입 선택자로 여러 요소 참조 - 리턴은 배열
                es[0].innerHTML="good";
            }

            var es = document.querySelectorAll('h4'); 
            es[1].onclick = function(){
                alert('bbb');
            }
        </script>
    </body>
</html>

BOM 모델 (브라우저 객체 모델)

원래 window.document이다. window.alert이다. 모든 js는 window부터 시작한다.

최상위 객체는 window이다.

window.setTimeout(함수, 몇초?) → 핸들러같은 녀석 ,근데 1번만 한다. ex ) 웹 광고

window.setInterval(함수, 몇초?) → 몇 초 주기로 계속한다. 인터벌을 제어하는 id를 주어 제어한다.

screen객체 : 모니터의 가로,세로 사이즈 (웹브라우저가아님)

location 객체 : 위도경도가 아니다. (지오로케이션) / 경로를 알려주는 객체

navigator 객체 : 웹브라우저의 코드네임, 이름, 버전정보 등 정보를 알려줌 → 새 기능은 여기 하위폴더에 들어가서 알아둬야한다.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>js BOM</title>
    </head>
    <body>
       
            <!-- 브라우저 오브젝트 모델 BOM : 웹 브라우저 제어 객체들을 모델링 -->

            <!-- //1. window : 최상위 객체 
                    이 객체의 주요 메소드는? open, close 새로운 웹 문서 열기/닫기-->
            
            <button onclick="aaa()">Naver</button>
            <script>
                function aaa(){
                    //window.open('https://www.naver.com'); //새탭이 열린다. 기본적으로 target값이 _blank이다 
                    //window.open('https://www.naver.com','_self'); //현재 페이지에서 열린다.
                    //아예 새창으로 열려면? 옵션을 줘야한다.
                    window.open('https://www.naver.com','_blank','width=500,height=200','left=200,top=50');
                }
            </script>
            <!-- 빈 윈도우 띄우기 -->
            <button onclick="bbb()">message 윈도우</button>
            <script>
                function bbb(){
                    //window는 최상위라서 생략 가능
                    win = open('','','width=500,height=200'); //(주소, 블랭크, 옵션) 전역으로 만들어서 다른 지역에서도 알아듣게 한다. 
                    win.document.write("잘못 들어왔어요?");
                }
            </script>

            <!-- 윈도우 닫기 -->
            <button onclick="ccc()">window close</button>
            <script>
                function ccc(){
                    win.close();
                }
            </script>

            <!-- moveTo, moveBy : 윈도우 창 이동 -->
            <button onclick="mmm()">move 윈도우</button>
            <button onclick="mmm2()"> 윈도우</button>

            <script>
                function mmm(){
                    win.moveTo(300,100);
                }

                function mmm2(){
                    win.moveBy(10,10); //현재 위치에서 변화량 
                    win.focus();
                }
            </script>

            <hr>
            <!-- setTImeout -->
            <button onclick="ddd()">3초후에 경고창 띄우기</button>
            <script>
                function ddd(){
                    setTimeout(function(){
                        alert('경고! ');
                    },3000);
                }
            </script>
            <hr>
            <input type="text" id="input1" value="0" readonly>

            <button onclick="eee()">카운트 증가 1초마다!</button>
            <button onclick="eee2()">카운트종료</button>

            <script>
                var show = function(){
                    var e = document.getElementById('input1');
                    //e.value = e.value+1; //이러면 결합연산자 
                    e.value = window.parseInt(e.value)+1; 
                }

                function eee(){
                    id = setInterval(show,1000); //show는 파라미터가 필요없다.
                    //특가할인에서 많이씀
                }

                function eee2(){
                    clearInterval(id);
                }
            </script>

            <hr>
            <!-- 그밖의 유용한 메소드들 -->
            <script>
                //인터넷 주소 URL에는 특수문자나 한글은 사용불가
                //이런 문자를 URL에 넣고 싶을때는 인코딩을 수행함
                //인코딩 함수 
                var a = encodeURI('http://www.test.com/가.html'); //http://www.test.com/%EA%B0%80.html
                //가라는 글자가 인코딩된다. 
                document.write(a+"<br>");

                var a2 = decodeURI(a);
                document.write(a2+"<br>");//http://www.test.com/가.html

                //eval() 함수
                var x = "10+2*6";
                document.write(eval(x)+"<br>"); //문자열을 js에 명령어로 인식하여 해독.

                //NaN
                document.write(isNaN(10)+"<br>" ); //숫자아닙니까? false
                document.write(isNaN("10")+"<br>" ); //isNaN의 뜻은 숫자로 바꿀수있냐라는 뜻이다. 
                document.write(isNaN("ab")+"<br>" ); //숫자아닙니까? 네 true
                document.write(isFinite("10/0")+"<br>" ); //유효한숫자가 아닙니까? 네 true

            </script>


            <!-- //2. document -->
            <!-- 원래는 window.document라고 써야하지만 window는 생략가능  -->

            <hr>
            <!-- //3. screen : 모니터 해상도 관리 객체 -->
            <script>
                document.write(window.screen.width+" , "+window.screen.height+"<br>");
                document.write(screen.width+" , "+screen.height+"<br>");
                document.write(screen.availWidth+" , "+screen.availHeight+"<br>"); //작업 표시줄 영역제외 사이즈(모니터사이즈임 브라우저가아님)
                
                //브라우저 창 사이즈를 알고싶다면... window객체에게 물어봐야한다..
                document.write(window.innerWidth+" , "+window.innerHeight+"<br>"); //document영역 : 브라우저의 하얀색
                document.write(window.outerWidth+" , "+window.outerHeight+"<br>"); //아우터는 브라우저의 전체영역


            </script>

            <!-- //4. location : URL 정보 -->
            <hr>
            <script>
                document.write(location.href+"<br>");
                document.write(location.protocol+"<br>");
                document.write(location.pathname+"<br>");
            </script>

            <button onclick="xxx()">location객체를 이용한 새로운 문서열기 </button>
            <button onclick="yyy()">location객체를 이용한 현재문서열기(새로고침) </button>
            <button onclick="zzz()">location객체를 이용한 현재문서 대체하여 열기 </button>
            
            <script>
                function xxx(){
                    //location.assign('https://www.naver.com'); //히스토리가 남아서 뒤로가기 가능
                    //assign은 자주쓰지 않는다.
                    location.href='https://www.naver.com';
                }
                function zzz(){
                    location.replace('https://www.naver.com'); //이렇게하면 히스토리가 안남음 finish하고 넘어간거임
                }
                function yyy(){
                    location.reload(); //새로 고침한거 
                }

            </script>

<hr>
            <!-- //5. history : 방문한 URL 정보-->
            <script>
                document.write("방문페이지 수 : "+history.length+"<br>");
            </script>

            <button onclick="hhh()">뒤로 </button>
            <button onclick="hhh2()">앞으로 </button>
            <button onclick="hhh3()">뒤로 2칸 </button>
            <script>

                function hhh(){
                    history.back();
                }

                function hhh2(){
                    history.forward();
                }

                function hhh3(){
                    history.go(-2);
                }

            </script>

            <!-- //6. navigator : 브라우저 정보 [추후 내 위치 검색할때 사용]-->
            <hr>
            <script>
                document.write(navigator.appCodeName+"<br>");
                document.write(navigator.appName+"<br>");
                document.write(navigator.appVersion+"<br>");
                document.write(navigator.platform+"<br>");
                document.write(navigator.userAgent+"<br>");
            </script>

       
    </body>
</html>

이벤트 처리

onclick

onload 바디요소에 쓴다. body가 끝나면 실행한다.

onunload

onchange 바꾸고 커서를다른데 찍었을때 실행

onmouseover

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>js 이벤트 처리</title>
        <script>
            //body 요소 안에 있는 h2요소를 제어해보기
            document.getElementById('aa').innerHTML="hello"; //텍스트를 변경시키려면? innerHTML (textContents 보다 낫다. )
            //이러면 head우선 실행되니까 이게 적용되지 않는다. 

            //요소의 load가 완료되는 이벤트에 콜백함수를 지정
            //js는 이벤트를 처리하는 방법을 3가지 제공
            //1. html에서 요소의 속성으로 이벤트 함수를 지정
            function loaded(){
                //바디의 load가 완료되면
                document.getElementById('aa').innerHTML = "Hello";

            //2. onclick은 너무 결합성이 크다. 다 onclick을 달고 수정하려고하면 너무 힘들다. 
            //이벤트처리를 요소 속성으로 하지말고
            //요소의 속성을 변경했던거처럼 이벤트 속성을 js로 지정
            document.getElementById('aa').onclick = function(){
                document.getElementById('aa').innerHTML += "Good";
            }

            //3.권장! 요소에 이벤트리스너를 추가 메소드 이용 : 다중이벤트 처리가능
            document.getElementById('aa').addEventListener('dblclick',function(){  //(어떤이벤트인데?, 함수)
                alert('double clicked');
            }); 

            }
            

        </script>
    </head>
    <body onload="loaded()">
        <!-- 1. 이벤트 처리 연습용[onload 이벤트] -->
        <h2 id="aa"></h2>

        <!-- 2. 다른 이벤트들의 종류 알아보기 -->
        <!-- 2.1 input 요소의 이벤트 -->
        <input type="text" id="in1" onfocus="aaa()">
        <input type="text" id="in2" onblur="bbb()" onchange="ccc()">
        <script>
            function aaa(){
                document.getElementById('in1').value="aa";
            }
            function bbb(){
                alert("blur");
            }
            function ccc(){
                alert("change");
            }
        </script>
        <hr>
        <!-- 사용자가 값을 입력하고 필드를 벗어나면 자동으로 대문자로 변경해주는 코드 -->
        <input type="text" id='in3' onchange="changeUp()">
        <script>
            function changeUp(){
                var e = document.getElementById('in3');
                var s = e.value;
                e.value = s.toUppercase(); 
            }
        </script>    
    
        <!-- 2.2 mouse 이벤트  -->
        <hr>
        
        <div style="width:200px; height:100px; background-color: yellow;"
        onmouseover="over(this)"
        onmouseout="out(this)"
        onmousemove="move(this)"></div>

        <script>
            function over(e){
                e.style.backgroundColor="red";
                e.style.border="2px solid white";
            }

            function out(e){
                e.style.backgroundColor="red";
                e.style.border="2px solid white";
            }

            var n=0;
            function move(e){
                n++;
                e.innerHTML="move : "+n;
            }
        </script>

        <hr>
        <div style="width:400px;height:100px; background-color: green;" id="kk"></div>
        <script>
            document.getElementById('kk').addEventListener('mousemove',function(event){
                //마우스의 이벤트 객체가 기본 파라미터로 전달되어옴
                var s="";
                s+="브라우저 문서 안에서의 좌표 : "+ event.clientX+" , "+event.clientY+"<br>";
                s+="모니터 기준 좌표 : "+ event.screenX+" , "+event.screenY+"<br>";
                s+="요소 영역 기준 좌표 : "+ event.offsetX+" , "+event.offsetY+"<br>";
                document.getElementById('kk').innerHTML = s;
            });
        </script>
        <!-- 2.3 키보드 이벤트 별도예제로 해보기 -->

    </body>
</html>

키보드

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>키보드 이벤트</title>

        <script>
            function keypress(){
                //키보드 이벤트는 window관리객체안에 event관리객체가 정보를 가지고 있다.
                var code = window.event.keyCode;
                document.getElementById('in1').value = code;
                //document.getElementById('in2').value = String.fromCharCode(code);
            }
        </script>
    </head>

    <body onkeypress="keypress()">
        <input type="text" id="in1">
        <input type="text" id="in2">

    </body>
</html>

폼의 유효성 검증

조건을 정해서 회원가입시키고 싶은데.. 이걸 해주는 유효성 검사

 

정규식

특정 규칙을 가지고 있는 문자열들을 표현하는 수식이다.

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>js 유효성 검사</title>
    </head>
    <body>
        <input type="text" id="in1">
        <button onclick="check()">유효성 검증 버튼</button>
        <h3 id="aa"></h3>

        <script>
            function check(){
                //검증용 정규표현식 
                var regExp = /^[a-zA-Z]+$/; //<<< /^[a-zA-Z]+$/ 이거 자체가 RegExp객체 , 영문자 한개 이상 꼭 있어야하는 조건
                var e = document.getElementById('in1');
                var s = e.value; //입력된 값
                //검증 2가지 방법
                //1. String.match() 메소드
                // if(s.match(regExp)) alert("OK");
                // else alert("요구하는 형식이 아닙니다. ");

                //2. RegExp 객체의 test() 메소드 
                // if(regExp.test(s)) alert("ok");
                // else alert("요구하는 형식이 아닙니다.");

                //정규표현식 연습
                regExp = /a/ ; //a라는 문자가 포함된 모든 입력 OK
                regExp = /A/ ; //A라는 문자가 포함된 모든 입력 OK
                regExp = /ab/ ; //ab라는 문자가 포함된 모든 입력 OK
                regExp = /^a/ ; //시작이 무조건 a여야 OK
                regExp = /^[a-z]/ ; //시작이 무조건 a여야 OK
                regExp = /a$/; //끝이 무조건 a
                regExp = /ab$/; //끝이 무조건 ab
                regExp = /^a$/; //a 한글자여야만 OK
                regExp = /^ab$/; //ab 한글자여야만 OK
                regExp = /^[a-z]$/; //영어 소문자 한글자여만 OK
                regExp = /^[a-zA-Z]$/; //영어 한글자여만 OK
                regExp = /^[a-zA-Z0-9]$/; //영어 한글자 or 숫자 한글자여만 OK
                regExp = /^[a-z]{2}$/; //영어 소문자 두글자여만 OK
                regExp = /^[a-z]{2,4}$/; //영어 소문자 2~4글자사이여만 OK
                regExp = /^[a-z]{4,}$/; //영어 소문자 4글자이상이여야만 OK
                regExp = /^\\w{2,}$/; // \\w는 문자나 숫자 모두를 말함. 문자 or 숫자 4글자 이상
                regExp = /^[a-z]*$/; //영어 소문자 0개이상이여야만 OK -> 즉 안써도 OK, 단 숫자가 들어가면 안됨
                regExp = /^[a-z]+$/; //영어 소문자 1개이상이여야만 OK -> 즉 안써도 OK, 단 숫자가 들어가면 안됨
                regExp = /^[a-z]?$/; //영어 소문자 1개 or 0개 이상이여야만 OK -> 즉 안써도 OK
                regExp = /^[5-9]$/; //숫자 5-9중에 1개 
                regExp = /^\\d$/; //숫자 1개 
                regExp = /^\\d\\d\\d$/; //숫자 3개 
                regExp = /^\\d\\d\\da\\d\\d\\da\\d\\d\\d$/; //숫자 3개, a ,숫자 3개, a ,숫자 3개 패턴

                //생년월일 형식 검증 ####-##-##
                regExp = /^\\d\\d\\d\\d-\\d\\d-\\d\\d$/;
                
                //이메일 형식 검증 ####@###.##
                regExp = /^[a-zA-z0-9!_]+@[a-zA-Z]+.[a-z]*$/;

                //url 주소가 맞는지 확인 가능
                regExp = /^http:$/;

                //혹시 /한개를 검증하고싶다면?
                regExp = /^\\/$/; //특수문자가 탈출하고 싶으면 역슬래시 \\

                var h = document.getElementById('aa');
                if(regExp.test(s)) h.innerHTML = "ok";
                else h.innerHTML = "불가";
            }
        </script>

    </body>
</html>
728x90
반응형

'HTML,CSS,JavaScript' 카테고리의 다른 글

JavaScript 게임만들기 , AJAX  (0) 2023.05.11
JavaScript Object  (0) 2023.05.09
JavaScript 자바 스크립트란?  (0) 2023.05.08
CSS3 부트스트랩  (0) 2023.05.04
CSS 회원가입 창 만들기  (0) 2023.05.03